2009-04-07 7 views
3

Ich suche nach einer Möglichkeit, ein datenbankgesteuertes Menü in ASP.NET MVC zu behandeln, das die MVC-Prinzipien nicht verletzt. Ich möchte das hartcodierte Standardmenü "Home, About" durch etwas aus meiner Datenbank ersetzen. Wie würde ich das anschließen? Würde ich einfach einen ContentPlaceHolder in meinem Site.Master einrichten und in meinen Views neu generiert? Das scheint mir nicht richtig zu sein.Die beste Methode, datenbankgesteuertes Menü in ASP.NET MVC zu verbinden

Antwort

2

Mein Hauptmenü ist ein ViewUserControl, das als Teilansicht in meiner MasterPage gerendert wird. Obwohl meins fest codiert ist, könnten Sie es einfach aus ViewData generieren. Aus Sichtdaten zu generieren, würde wahrscheinlich ein benutzerdefiniertes FilterAttribute implementieren, das die Parameter angibt, die beim Generieren des Menüs für jeden Controller/Aktion verwendet werden, oder, wenn das Menü auf jeder Seite dasselbe ist, einen Basiscontroller implementieren, der füllt in der Ansicht Daten durch Überschreiben OnActionExecuted und Hinzufügen zu den ViewData in ihm.

Beispiel (Hinweis, Sie würden wahrscheinlich Caching für die Ergebnisse verwenden, anstatt sie jedes Mal aus der db zu holen).

Modellklassen

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: vom Typ 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> 

Master

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

Base

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

Alle Links und/oder Artikel zu dieser Methode? –

+0

Ich habe mich über Google umgeschaut und konnte nichts finden, was mit RTM zu tun hat. Das meiste davon waren ältere Sachen, die nicht wirklich auf die veröffentlichte Version anwendbar sind. Ich werde sehen, ob ich ein Beispiel hinzufügen kann. – tvanfosson

+0

Äh, ich weiß nicht so viel über MVC, aber ist das performant? Geht das zur Datenbank mit einer Unterabfrage, nur um das Menü für jede Seitenanfrage zu bekommen? – flipdoubt

Verwandte Themen