Best way to wire up database-driven menu in ASP.NET MVC

前端 未结 1 1498
慢半拍i
慢半拍i 2021-02-03 15:54

I\'m looking for a way to handle a database-driven menu in ASP.NET MVC that doesn\'t violate the MVC principles. I want to replace the hard-coded, default, \"Home, About\" menu

1条回答
  •  醉酒成梦
    2021-02-03 16:28

    My main menu is a ViewUserControl that is rendered as a partial view in my MasterPage. Although mine is hard-coded, you could easily generate it from ViewData. Generating it from view data would probably involve implementing either a custom FilterAttribute that specified the parameters to use in generating the menu that would be applied to each controller/action or, if the menu is the same on each page, implementing a base controller that fills in the view data by overriding OnActionExecuted and adding to the ViewData in it.

    Example (note, you'd probably use caching for the results instead of getting them from the db each time).

    Model classes

    public class MenuItem
    {
        public string Text { get; set; }
        public string Action { get; set; }
        public string Controller { get; set; }
    }
    
    public class Menu
    {
         public string Heading { get; set; }
         public IEnumerable Items { get; set; }
    }
    

    MenuControl.ascx : of type System.Web.Mvc.ViewPage>

    
    

    MasterPage

    
    
    ...
    
    
    
    
    ... other HTML...
    
    <% Html.RenderPartial( "MenuControl", ViewData["mainMenu"], ViewData ); %>
    
    
    
    ... more HTML ...
    
    
    
    

    BaseController

    public override void OnActionExecuted( ActionExecutedContext filterContext )
    {
         if (filterContext != null)
         {
             var context = filterContext.Result as ViewResult;
             if (context != null) {
                 context.ViewData["mainMenu"] = 
                     db.MenuData.Where( m => m.Type == "mainMenu" )
                                .Select( m => new Menu {
                                    Heading = m.Heading,
                                    Items = db.ItemData.Where( i => i.MenuID == m.MenuID )
                                                   .OrderBy( i => i.Name )
                                                   .Select( i => new MenuItem {
                                                       Text = i.Text,
                                                       Action = i.Operation,
                                                       Controller = i.Table
                                                   })
                                });
             }
        }
    }
    

    0 讨论(0)
提交回复
热议问题