对整个区域使用共享控制器类

本文关键字:共享 控制器 区域 | 更新日期: 2023-09-27 18:26:25

我的mvc应用程序上有一个区域"Admin",每个页面都有自己的控制器。像PageController和ModuleController等。在我的共享布局文件(View/shared/_LayoutAdmin.chtml)上,菜单被动态加载到@model var中。现在在我的HomeController中,我有了获取菜单的方法:

    public ActionResult Index()
    {
        var model = _db.Menus.Include("MenuItems").First(m => m.Name == "Admin menu");
        ViewBag.AdminMenu = new MenuModelView
        {
            Name = model.Name,
            CssClass = model.CssClass,
            CssId = model.CssId,
            Deleted = model.Deleted,
            MenuItems = model.MenuItems
        };
        return View();
    }

每个控制器类都需要这个代码块。我不认为复制这个代码是最好的主意。所以我想知道是否有可能在整个Admin区域的共享控制器类中使用这个方法。类似于Shared/_LayoutAdmin.chtml文件的代码隐藏类。

对整个区域使用共享控制器类

是的,你可以。。。您可以使用继承来创建一个有效的共享控制器类。就像这样…

Public Class AdminBaseController : Controller {
    public ActionResult Index()
        {
            var model = _db.Menus.Include("MenuItems").First(m => m.Name == "Admin menu");
            ViewBag.AdminMenu = new MenuModelView
            {
                Name = model.Name,
                CssClass = model.CssClass,
                CssId = model.CssId,
                Deleted = model.Deleted,
                MenuItems = model.MenuItems
            };
            return View();
        }
    }

然后你可以构建所有其他控制器来继承它,就像这样:

Public Class AdminController1 : AdminBaseController

对于应该在整个特定区域重复的菜单,您需要使用子操作:

[ChildActionOnly]
public ActionResult AdminMenu()
{
    var menu = _db.Menus.Include("MenuItems").First(m => m.Name == "Admin menu");
    var model = new MenuModelView
    {
        Name = menu.Name,
        CssClass = menu.CssClass,
        CssId = menu.CssId,
        Deleted = menu.Deleted,
        MenuItems = menu.MenuItems
    };
    return PartialView("_AdminMenu", model);
}

我更改了您的代码,这样您就可以将视图模型传递给视图,而不是将其填充到ViewBag中。不要使用ViewBag。太可怕了

_AdminMenu.cshtml

@model Namespace.To.MenuModelView
<!-- render your menu and just your menu here -->

Areas''Admin''Views''Shared''_Layout.cs.html

...
<!-- place this where you want the menu to appear in your layout -->
@Html.Action("AdminMenu", "ControllerNameWhereChildActionExists")
...

我会考虑是否可以将布局中需要此数据的UI封装为分部。在哪种情况下来自:

_LayoutAdmin.cshtml

...
@{Html.RenderAction("Index", "AdminLayout")}
...

因此,您将有一个带有索引操作的AdminLayoutController和视图,该视图只是包含菜单的部分视图。