Usuário com melhor resposta
Dados na View Layout

Pergunta
-
Pessoal, bom dia.
Eu estou tentando criar um menu lateral que será populado de acordo com o que eu tiver inserido numa determinada tabela.
Por exemplo: Inseri na tabela "Favorites": 'Palmeiras', 'Corinthians', 'São Paulo'.
Gostaria que no menu lateral (que vai estar presente em todas as paginas) aparecesse:
-Favoritos
--Palmeiras
--Corinthians
--São PauloEu até consegui, criando uma ViewData na ActionResult de um controller, e fazendo um foreach na Layout.cshtml, porém, com esse método, eu terei que criar esta ViewData em TODOS os meus ActionResult.
Deve ter uma maneira mais limpa e prática de fazer isso, não?
Segue meu código atual:
public ActionResult Index() { string userId = User.Identity.GetUserId(); ViewData["favSections"] = db.FavoriteSections.Include(x => x.Section).Where(x => x.User.Id == userId).ToList(); return View(); }
<h5>Favoritos</h5> @foreach (var i in (IEnumerable<Zorum.Models.FavoriteSections>)ViewData["favSections"]) { @Html.ActionLink(i.Section.SectionName, "Index", "Section", new { id = i.Section.SectionId }, new { id = i.Section.SectionId })<br /> }
Obrigado :)
Leonardo D'Amato
Respostas
-
Crie o seu menu como uma partialview. Depois adicione no seu layout desta maneira:
@{Html.RenderAction("Menu", "Home");}
No seu controler:
public ActionResult Menu() { string userId = User.Identity.GetUserId(); IEnumerable<Zorum.Models.FavoriteSections>listFavorites =new IEnumerable<Zorum.Models.FavoriteSections>(); listFavorites = db.FavoriteSections.Include(x => x.Section).Where(x => x.User.Id == userId).ToList(); return PartialView(listFavorites); }
e sua partialview:
@model IEnumerable<Zorum.Models.FavoriteSections> <h5>Favoritos</h5> @foreach (var i in Model) { @Html.ActionLink(i.Section.SectionName, "Index", "Section", new { id = i.Section.SectionId }, new { id = i.Section.SectionId })<br /> }
Desta forma, independente, da view que voce carregue que use o layout em questao, o menu sera renderizado à partir do seu proprio controler.
Outra forma, que eu nao recomendo, seria criar um controler que preenche a viewdata com os favoritos e depois herdar em todos os controlers
deste jeito:
public class BaseController : Controller { protected override void OnActionExecuted(ActionExecutedContext filterContext) { var controller = filterContext.Controller as BaseController; if (controller != null) { string userId = User.Identity.GetUserId();
ViewData["favSections"] = db.FavoriteSections.Include(x => x.Section).Where(x => x.User.Id == userId).ToList(); } } }
e depois em cada um dos controlers:
public class HomeController : BaseController
ao inves de
public class HomeController : Controller
A escolha é sua... nao escolha o bulbasauro :P
Att
William John Adam Trindade
Analyste-programmeur
----------------------------------------------------------
- Marcado como Resposta Leonardo N. D'Amato quarta-feira, 18 de novembro de 2015 17:11
-
>- Eu crio a View vazia, e marco como partialView, até aí ok. Aí então eu crio um novo controller para colocar essa ActionResult, ou coloco em algum existente?
Vai depender de onde voce cria a partialview.. se voce colocar no Home, use o controler de homecontrole.. agora se voce criar uma diretorio novo para essa view, por exemplo Menu, ai vai ter que ser dentro de MenuControler.
>Eu troco o conteúdo da View Layout por esta linha ou apenas adiciono em algum lugar do código
Se voce faz referencia à isso:
@{Html.RenderAction("Menu", "Home");}
coloque no mesmo lugar onde voce tinha isso:
<h5>Favoritos</h5> @foreach (var i in (IEnumerable<Zorum.Models.FavoriteSections>)ViewData["favSections"]) { @Html.ActionLink(i.Section.SectionName, "Index", "Section", new { id = i.Section.SectionId }, new { id = i.Section.SectionId })<br /> }
creio que o codigo acima estava no layout, certo?
Att
William John Adam Trindade
Analyste-programmeur
----------------------------------------------------------
- Editado William John Adam TrindadeModerator quarta-feira, 18 de novembro de 2015 16:05
- Marcado como Resposta Leonardo N. D'Amato quarta-feira, 18 de novembro de 2015 17:11
Todas as Respostas
-
Crie o seu menu como uma partialview. Depois adicione no seu layout desta maneira:
@{Html.RenderAction("Menu", "Home");}
No seu controler:
public ActionResult Menu() { string userId = User.Identity.GetUserId(); IEnumerable<Zorum.Models.FavoriteSections>listFavorites =new IEnumerable<Zorum.Models.FavoriteSections>(); listFavorites = db.FavoriteSections.Include(x => x.Section).Where(x => x.User.Id == userId).ToList(); return PartialView(listFavorites); }
e sua partialview:
@model IEnumerable<Zorum.Models.FavoriteSections> <h5>Favoritos</h5> @foreach (var i in Model) { @Html.ActionLink(i.Section.SectionName, "Index", "Section", new { id = i.Section.SectionId }, new { id = i.Section.SectionId })<br /> }
Desta forma, independente, da view que voce carregue que use o layout em questao, o menu sera renderizado à partir do seu proprio controler.
Outra forma, que eu nao recomendo, seria criar um controler que preenche a viewdata com os favoritos e depois herdar em todos os controlers
deste jeito:
public class BaseController : Controller { protected override void OnActionExecuted(ActionExecutedContext filterContext) { var controller = filterContext.Controller as BaseController; if (controller != null) { string userId = User.Identity.GetUserId();
ViewData["favSections"] = db.FavoriteSections.Include(x => x.Section).Where(x => x.User.Id == userId).ToList(); } } }
e depois em cada um dos controlers:
public class HomeController : BaseController
ao inves de
public class HomeController : Controller
A escolha é sua... nao escolha o bulbasauro :P
Att
William John Adam Trindade
Analyste-programmeur
----------------------------------------------------------
- Marcado como Resposta Leonardo N. D'Amato quarta-feira, 18 de novembro de 2015 17:11
-
William, explicação muito boa, como sempre.
Vou realizar o primeiro método, pois parece ser muito mais profissional. :)
Eu só não entendi duas coisas.
- Eu crio a View vazia, e marco como partialView, até aí ok. Aí então eu crio um novo controller para colocar essa ActionResult, ou coloco em algum existente?
- Eu troco o conteúdo da View Layout por esta linha ou apenas adiciono em algum lugar do código?
Obrigado, William
Um abraço.-------------------- EDIT--------------------
William, estou obtendo um erro nesta parte:
IEnumerable<Zorum.Models.FavoriteSections>listFavorites =new IEnumerable<Zorum.Models.FavoriteSections>(); listFavorites = db.FavoriteSections.Include(x => x.Section).Where(x => x.User.Id == userId).ToList();
O erro é: Cannot create an instance of the abstract class or interface
Grato!
Leonardo D'Amato
- Editado Leonardo N. D'Amato quarta-feira, 18 de novembro de 2015 16:05
-
>- Eu crio a View vazia, e marco como partialView, até aí ok. Aí então eu crio um novo controller para colocar essa ActionResult, ou coloco em algum existente?
Vai depender de onde voce cria a partialview.. se voce colocar no Home, use o controler de homecontrole.. agora se voce criar uma diretorio novo para essa view, por exemplo Menu, ai vai ter que ser dentro de MenuControler.
>Eu troco o conteúdo da View Layout por esta linha ou apenas adiciono em algum lugar do código
Se voce faz referencia à isso:
@{Html.RenderAction("Menu", "Home");}
coloque no mesmo lugar onde voce tinha isso:
<h5>Favoritos</h5> @foreach (var i in (IEnumerable<Zorum.Models.FavoriteSections>)ViewData["favSections"]) { @Html.ActionLink(i.Section.SectionName, "Index", "Section", new { id = i.Section.SectionId }, new { id = i.Section.SectionId })<br /> }
creio que o codigo acima estava no layout, certo?
Att
William John Adam Trindade
Analyste-programmeur
----------------------------------------------------------
- Editado William John Adam TrindadeModerator quarta-feira, 18 de novembro de 2015 16:05
- Marcado como Resposta Leonardo N. D'Amato quarta-feira, 18 de novembro de 2015 17:11
-
Se voce já esta usando o MVC6 tem uma maniera mais elegante ainda (eu esqueci que agora existe isso)
http://weblogs.asp.net/ricardoperes/asp-net-5-view-components
Voce pode criar um componente (como era feito no Windows Forms)
Note que um viewcomponente nao herda de um controler
http://docs.asp.net/projects/mvc/en/latest/views/view-components.html
Mas como ainda esta em beta, eu vou esperar para começar a usar em produçao.
att
William John Adam Trindade
Analyste-programmeur
----------------------------------------------------------
-
William, ficou perfeito, cara.
Criei um novo controller dedicado ao Menu, pois terão mais Views necessárias para completá-lo.
Minha aplicação está em MVC5. Talvez quando eu tiver mais conhecimento, analise como fazer a migração, caso seja possível!
Obrigado, mais uma vez!
Um abraçoLeonardo D'Amato
-
William, explicação muito boa, como sempre.
Vou realizar o primeiro método, pois parece ser muito mais profissional. :)
Eu só não entendi duas coisas.
- Eu crio a View vazia, e marco como partialView, até aí ok. Aí então eu crio um novo controller para colocar essa ActionResult, ou coloco em algum existente?
- Eu troco o conteúdo da View Layout por esta linha ou apenas adiciono em algum lugar do código?
Obrigado, William
Um abraço.-------------------- EDIT--------------------
William, estou obtendo um erro nesta parte:
IEnumerable<Zorum.Models.FavoriteSections>listFavorites =new IEnumerable<Zorum.Models.FavoriteSections>(); listFavorites = db.FavoriteSections.Include(x => x.Section).Where(x => x.User.Id == userId).ToList();
O erro é: Cannot create an instance of the abstract class or interface
Grato!
oops.. falha minha. Voce nao pode criar um objeto à partir de uma interface..
O correto é
List<Zorum.Models.FavoriteSections>listFavorites =new List<Zorum.Models.FavoriteSections>();
List implementa IEnumerable.
William John Adam Trindade
Analyste-programmeur
----------------------------------------------------------