none
Dados na View Layout RRS feed

  • 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 Paulo

    Eu 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

    quarta-feira, 18 de novembro de 2015 14:01

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
    ----------------------------------------------------------

    quarta-feira, 18 de novembro de 2015 14:54
    Moderador
  • >- 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
    ----------------------------------------------------------



    quarta-feira, 18 de novembro de 2015 16:04
    Moderador

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
    ----------------------------------------------------------

    quarta-feira, 18 de novembro de 2015 14:54
    Moderador
  • 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


    quarta-feira, 18 de novembro de 2015 15:46
  • >- 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
    ----------------------------------------------------------



    quarta-feira, 18 de novembro de 2015 16:04
    Moderador
  • 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
    ----------------------------------------------------------

    quarta-feira, 18 de novembro de 2015 16:19
    Moderador
  • 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ço


    Leonardo D'Amato

    quarta-feira, 18 de novembro de 2015 16:46
  • 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
    ----------------------------------------------------------

    quarta-feira, 18 de novembro de 2015 16:52
    Moderador