Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/csharp-4.0/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net mvc 将控制器用于局部视图_Asp.net Mvc_Layout_Menu_Entity Framework 6_Asp.net Mvc Partialview - Fatal编程技术网

Asp.net mvc 将控制器用于局部视图

Asp.net mvc 将控制器用于局部视图,asp.net-mvc,layout,menu,entity-framework-6,asp.net-mvc-partialview,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

在企业级应用程序中,所有(好的,几乎所有)内容都需要可配置。这就是为什么我创建了一个菜单和菜单项模型,允许管理员创建多个菜单:

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; }
}
公共类菜单
{
[关键]
公共int ID{get;set;}
公共字符串标题{get;set;}
公共字符串说明{get;set;}
公共虚拟ICollection菜单项{get;set;}
}
公共类菜单项
{
[关键]
公共int ID{get;set;}
公共int?MenuID{get;set;}
public int?ParentMenuItemID{get;set;}
公共虚拟标识角色{get;set;}
公共字符串名称{get;set;}
公共字符串区域{get;set;}
公共字符串控制器{get;set;}
公共字符串操作{get;set;}
公共字符串Url{get;set;}
公共字符串CssClass{get;set;}
公共字符串图标{get;set;}
公共虚拟ICollection菜单项{get;set;}
公共虚拟菜单{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>
  • @foreach(Model.MenuItems中的var m) { if(m.Role==null | | User.IsInRole(m.Role.Name)) {
  • @如果(m.MenuItems!=null&&m.MenuItems.Count>0) {
      @foreach(m.MenuItems中的var mi) { if(mi.Role==null | | User.IsInRole(mi.Role.Name)) {
    • } }
    }
  • } }
为了测试我的当前代码,我在布局视图中硬编码了一个菜单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>

@Html.Partial(“_LeftMenu”,new MyAppContext().Menus.Find(1))
@RenderBody()
现在,出现了几个问题,首先,我需要能够将菜单ID传递给partial,以便它能够呈现正确的菜单。通过使用局部视图方法,我不知道实现此目标的方法。其次,当我对正在加载的菜单应用安全性时,菜单项以相反的顺序显示。因此,通过使用某种类型的控制器来执行菜单和布局的数据逻辑,它应该可以解决这个问题


那么,有人对我需要走的方向有什么建议吗?我开始认为我尝试使用菜单的局部视图(动态)是一个坏主意?

您可以使用带有操作方法的控制器,并使用@Html.RenderAction代替@Html.partial方法,而不是直接调用@Html.partial。 在action方法中,您可以传递id,还可以应用所需的安全逻辑,并且在视图中只需迭代菜单集合并显示所需的菜单。
这将使您的UI保持干净。

我想我已经做到了:
@{Html.RenderAction(“UserMenuAction”,“Menu”,new{area=“Admin”,id=1});}
,但现在我遇到了一个问题。我根据控制器和/或页面区域选择“活动”菜单项。现在,菜单总是返回管理区域,因为这是正在使用的控制器(
ViewContext.RouteData.Values[“controller”].ToString()
ViewContext.RouteData.DataTokens[“area”]
)。有什么建议吗?我不认为您可以使用这种逻辑来选择菜单项。您可能希望将所选菜单的状态添加到会话或添加到ViewBag,并使用它来显示活动菜单项。还有其他更好的方法,但这取决于具体项目的组织方式。我最终通过了区域、控制器、,从_布局到UserMenuAction的操作,效果非常好!谢谢你朝着正确的方向轻推。