Лучший способ подключить меню на основе базы данных в ASP.NET MVC - PullRequest
3 голосов
/ 07 апреля 2009

Я ищу способ обработки меню на основе базы данных в ASP.NET MVC, который не нарушает принципы MVC. Я хочу заменить жестко заданное по умолчанию меню «Домой, О программе» чем-то из моей базы данных. Как бы я подключил это? Могу ли я просто установить ContentPlaceHolder на моем Site.Master и восстановить его в своих представлениях? Мне это не кажется правильным.

1 Ответ

2 голосов
/ 07 апреля 2009

Мое главное меню - это ViewUserControl, который отображается как частичное представление в моей мастер-странице. Хотя мой жестко запрограммирован, вы можете легко сгенерировать его из 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<List<Menu>>

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

MasterPage

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

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
                                               })
                            });
         }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...