我的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文件的类后面的代码一样。
答案 0 :(得分:2)
是的,你可以......你可以使用继承来创建有效的共享控制器类。像这样......
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
答案 1 :(得分:1)
对于类似于应在整个特定区域重复的菜单,您希望使用子操作:
[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 -->
<强>领域\管理员\视图\共享\ _Layout.cshtml 强>
...
<!-- place this where you want the menu to appear in your layout -->
@Html.Action("AdminMenu", "ControllerNameWhereChildActionExists")
...
答案 2 :(得分:0)
我会考虑是否可以将布局中需要此数据的UI封装为部分。在这种情况下:
...
@{Html.RenderAction("Index", "AdminLayout")}
...
因此,您的索引操作会有AdminLayoutController
,而视图只是包含菜单的部分视图。