【问题标题】:Best way to wire up database-driven menu in ASP.NET MVC在 ASP.NET MVC 中连接数据库驱动菜单的最佳方法
【发布时间】:2010-10-17 23:06:17
【问题描述】:

我正在寻找一种在不违反 MVC 原则的 ASP.NET MVC 中处理数据库驱动菜单的方法。我想用我的数据库中的内容替换硬编码的默认“主页,关于”菜单。我该如何接线?我会在我的 Site.Master 中设置一个 ContentPlaceHolder 并在我的视图中重新生成吗?这对我来说似乎不对。

【问题讨论】:

    标签: asp.net-mvc linq-to-sql .net-3.5 master-pages


    【解决方案1】:

    我的主菜单是一个 ViewUserControl,它在我的 MasterPage 中呈现为部分视图。虽然我的是硬编码的,但您可以轻松地从 ViewData 生成它。从视图数据生成它可能涉及实现一个自定义 FilterAttribute,该属性指定用于生成将应用于每个控制器/动作的菜单的参数,或者,如果每个页面上的菜单相同,则实现一个基本控制器来填充通过覆盖 OnActionExecuted 并添加到其中的 ViewData 在视图数据中。

    示例(注意,您可能会对结果使用缓存,而不是每次都从数据库中获取它们)。

    模型类

    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<MenuItem> Items { get; set; }
    }
    

    MenuControl.ascx : 类型为System.Web.Mvc.ViewPage&lt;List&lt;Menu&gt;&gt;

    <div id="mainMenu">
    <% foreach (var menu in Model) { %>
       <div class="menu">
          <h2 class="menu-heading"><%= menu.Heading %></h2>
          <% foreach (var item in Model.Items) { %>
             <%= Html.ActionLink( item.Text,
                                  item.Action,
                                  item.Controller,
                                  null,
                                  { @class = "menu-item" } ) %>
          <% } %>
       </div>
    <% } %>
    </div>
    

    母版页

    <html>
    <head>
    ...
    <asp:ContentPlaceHolder runat="server" id="HeaderContent">
    </head>
    <body>
    
    ... other HTML...
    
    <% Html.RenderPartial( "MenuControl", ViewData["mainMenu"], ViewData ); %>
    
    <asp:ContentPlaceHolder runat="server" id="BodyContent" />
    
    ... more HTML ...
    
    </body>
    </html>
    

    基础控制器

    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
                                                   })
                                });
             }
        }
    }
    

    【讨论】:

    • 任何与此方法相关的链接和/或文章?
    • 我通过谷歌环顾四周,找不到与 RTM 相关的任何内容。其中大部分是旧的东西,并不真正适用于已发布的版本。我看看能不能加个例子。
    • 呃,我对 MVC 了解不多,但是这个性能好吗?这是否通过子查询进入数据库只是为了获取每个页面请求的菜单?
    • @flipdoubt -- 这只是一个展示你如何做到这一点的例子。正如我在回答中所说,我的菜单是静态的。如果它们来自数据库,您可能会缓存它们。
    猜你喜欢
    • 1970-01-01
    • 2011-01-22
    • 1970-01-01
    • 1970-01-01
    • 2010-12-30
    • 1970-01-01
    • 1970-01-01
    • 2020-06-29
    • 2016-04-29
    相关资源
    最近更新 更多