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

时间:2014-10-14 14:35:45

标签: c# asp.net-mvc

我的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文件的类后面的代码一样。

3 个答案:

答案 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封装为部分。在这种情况下:

_LayoutAdmin.cshtml

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

因此,您的索引操作会有AdminLayoutController,而视图只是包含菜单的部分视图。