使用Controller进行部分视图

时间:2014-10-29 13:59:48

标签: asp.net-mvc layout menu entity-framework-6 asp.net-mvc-partialview

在企业级应用程序中,一切(好吧,差不多)都需要配置。这就是为什么我创建了一个菜单和菜单项模型,允许管理员创建多个菜单:

public class Menu
{
    [Key]
    public int ID { get; set; }
    public string Title { get; set; }
    public string Description { get; set; }
    public virtual ICollection<MenuItem> MenuItems { get; set; }
}

public class MenuItem
{
    [Key]
    public int ID { get; set; }
    public int? MenuID { get; set; }
    public int? ParentMenuItemID { get; set; }
    public virtual IdentityRole Role { get; set; }
    public string Name { get; set; }
    public string Area { get; set; }
    public string Controller { get; set; }
    public string Action { get; set; }
    public string Url { get; set; }
    public string CssClass { get; set; }
    public string Icon { get; set; }
    public virtual ICollection<MenuItem> MenuItems { get; set; }
    public virtual Menu Menu { get; set; }
}

我试图让他们能够在局部视图中渲染特定菜单,该菜单将在布局视图中呈现,并应用安全性:

<ul>
    <li>
        <div class="sidebar-toggler hidden-phone"></div>
    </li>
    <li>
        <form class="sidebar-search">
            <div class="input-box">
                <a href="javascript:;" class="remove"></a>
                <input type="text" placeholder="Search..." />
                <input type="button" class="submit" value=" " />
            </div>
        </form>
    </li>
    @foreach (var m in Model.MenuItems)
    {
        if (m.Role == null || User.IsInRole(m.Role.Name))
        {
            <li class="@(m.MenuItems != null && m.MenuItems.Count > 0 ? "has-sub " : "") @(ViewContext.RouteData.Values["Controller"].ToString() == m.Controller || (ViewContext.RouteData.DataTokens["area"] != null && ViewContext.RouteData.DataTokens["area"].ToString() == m.Area) ? "active " : " ") ">
                <a href="@Url.Action(m.Action, m.Controller, new { area = (string.IsNullOrEmpty(m.Area) ? "" : m.Area) }, null)">
                    @if (!string.IsNullOrEmpty(m.Icon))
                    {
                        <i class="@m.Icon"></i>
                    }
                    <span class="title">@m.Name</span>
                    @if (ViewContext.RouteData.Values["Controller"].ToString() == m.Controller || (ViewContext.RouteData.DataTokens["area"] != null && ViewContext.RouteData.DataTokens["area"].ToString() == m.Area))
                    {
                        <span class="selected"></span>
                    }
                </a>
                @if (m.MenuItems != null && m.MenuItems.Count > 0)
                {
                    <ul class="sub">
                        @foreach (var mi in m.MenuItems)
                        {
                            if (mi.Role == null || User.IsInRole(mi.Role.Name))
                            {
                                <li class="@(ViewBag.Title == mi.Name ? "active" : "")">
                                    <a href="@Url.Action(mi.Action, mi.Controller, new { area = mi.Area })">@mi.Name</a>
                                </li>
                            }
                        }
                    </ul>
                }
            </li>
        }
    }
</ul>

为了测试我当前的代码,我在布局视图中对菜单ID进行了硬编码:

<div class="page-container row-fluid">
    <div class="page-sidebar nav-collapse collapse">
        @Html.Partial("_LeftMenu", new MyAppContext().Menus.Find(1))
    </div>
    <div class="page-content">
        @RenderBody()
    </div>
</div>

现在,出现了一些问题,首先,我需要能够将菜单ID传递给部分,以便呈现正确的菜单。通过使用局部视图方法,我不知道如何实现这一目标。其次,当我将安全性应用于正在加载的菜单时,菜单项以相反的顺序显示。因此,通过使用某种类型的控制器来执行菜单和布局的数据逻辑,它应该可以解决这个问题。

那么,任何人都有任何关于我需要进入的方向的建议吗?我开始认为我尝试使用部分视图进行菜单(动态)是一个坏主意吗?

1 个答案:

答案 0 :(得分:1)

您可以使用@ Html.RenderAction代替@ Html.Partial方法,而不是直接调用@ Html.Partial。 在action方法中,您可以传递id并应用所需的安全逻辑,并在视图中迭代菜单集并显示所需的菜单。 这将使您的UI保持清洁。