在asp.net-mvc中,使用Base ViewModel在Site.Master页面上显示动态内容的最佳方法是什么

时间:2010-11-06 23:37:32

标签: c# asp.net-mvc viewmodel

我有一个asp.net-mvc网站,我希望在每个页面上显示一些信息。我创建了一个名为BaseViewModel的类,每个viewModel类都继承自BaseViewModel。 Site.Master视图直接绑定到BaseViewModel。

现在,基类有一个名为MenuLinks的属性。

menulinks属性从数据库调用中填充,因此在每个控制器操作上正在调用ViewModel我正在添加一个新行:

 viewModel.MenuLinks = _repository.GetMenuLinks();

我有很多控制器,动作和视图模型。有没有更清洁的方法,我可以做到上述,而不必将这一行放在每一个控制器动作上面。

5 个答案:

答案 0 :(得分:11)

您可以编写一个自定义action filter attribute,它将在每个操作后执行并设置基本模型的属性:

public override void OnActionExecuted(ActionExecutedContext filterContext)
{
    base.OnActionExecuted(filterContext);
    var viewResult = filterContext.Result as ViewResultBase;
    if (viewResult != null) 
    {
        var model = viewResult.ViewData.Model as BaseViewModel;
        if (model != null)
        {
            model.MenuLinks = _repository.GetMenuLinks();
        }
    }
}

现在剩下的就是用这个动作过滤器来装饰你的基本控制器。

另一种处理方法是使用child actions而没有基本视图模型。

答案 1 :(得分:2)

在您的site.master页面中

,请致电

<div id="menu-link">
  <% Html.RenderAction("Action", "Controller"); %>
</div>

如果你愿意,你可以在你的家庭控制器中调用一个动作,只是让它返回html的局部视图,在你的情况下是一些菜单链接。

public class HomeController: Controller
{
    public ViewResult Menu() {
        var viewModel = new ViewModel();
        viewModel.MenuLinks = _repository.GetMenuLinks();

        return PartialView("MenuPartial", viewModel);
    }
}

您可以创建部分“MenuPartial.ascx”

<% foreach(var link in Model.MenuLinks) { %>
    <%: link.Name %>
<% }%> 

答案 2 :(得分:2)

我喜欢justins的例子,因为它使用了MVC方法。我修改了它,因此它适用于带剃须刀的MVC3。 这是我在_Layout.cshtml中的内容:

        <div id="menucontainer">
            <ul id="menu">
                @Html.Action("Menu","Layout")
            </ul>
        </div>

我创建了一个LayoutController,其菜单操作如下:

public class LayoutController : Controller
{
    //
    // GET: /Layout/
    public PartialViewResult Menu()
    {
        var viewModel = new MenuViewModel {IsAdministrator = true};

        return PartialView(viewModel);
    }
}

其中呈现部分视图名称Menu.cshtml

@model MenuViewModel
@if (Model.IsAdministrator)
{
   //render admin stuff
}
//render other items

答案 3 :(得分:0)

我认为在不修改所有控制器操作的情况下实现结果的最佳方法是创建一个自定义操作过滤器,使用菜单链接填充BaseModel的属性。

然后你可以有一个BaseController类并将该属性添加到BaseController。

答案 4 :(得分:0)

创建工厂类,为您提供已配置的视图模型。

Class Factory{

  Repository _repository;

  public Factory(Repository repository){
    _repository = repository;
  }

  public ViewModel GetViewModel(){
    var viewModel = new ViewModel();
    viewModel.MenuLinks = _repository.GetMenuLinks();
    return viewModel;
  }

}

然后在您的控制器中,您可以使用Factory类,而不是直接创建viewModel

的实例
   ... your controller ...
   var factory = new Factory(_repository);
   var viewMolde = factory.GetViewModel();