2009-04-07 5 views
3

MVCの原則に違反しないASP.NET MVCのデータベース駆動メニューを処理する方法を探しています。私は、ハードコードされたデフォルトの "Home、About"メニューを自分のデータベースから何かに置き換えたいと思います。どのように私はこれを配線しますか?私は自分のSite.MasterにContentPlaceHolderを設定して、自分のビューに再生成しましたか?それは私にとって正しいとは思わない。ASP.NET MVCのデータベース駆動メニューを結ぶのに最適な方法

答えて

2

私のメインメニューは、私のMasterPageで部分的に表示される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> 

のマスターページ

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

この方法に関連するリンクや記事はありますか? –

+0

私はGoogleを見回し、RTMに関連するものは何も見つかりませんでした。そのほとんどは、リリースされたバージョンには実際には適用されない古いものでした。私は例を加えることができるかどうかを見ていきます。 – tvanfosson

+0

まあ、私はそれほどMVCについてはわかりませんが、この演技者ですか?これは、各ページリクエストのメニューを取得するためにサブクエリを使用してデータベースに移動しますか? – flipdoubt