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

发布于 2024-09-30 14:53:01 字数 380 浏览 1 评论 0原文

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

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

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

 viewModel.MenuLinks = _repository.GetMenuLinks();

我有很多控制器、操作和视图模型。有没有更干净的方法可以完成上述操作,而不必将此行放在每个控制器操作上方。

i have an asp.net-mvc site and there is some information that i want to show on every page. I have created a class called BaseViewModel and each of the viewModel classes inherit from BaseViewModel. The Site.Master view binds to the BaseViewModel directly.

Right now the base class has one property called MenuLinks.

The menulinks property gets populated from a database call so on every controller action that is instatiating a ViewModel i am adding a new line:

 viewModel.MenuLinks = _repository.GetMenuLinks();

i have a lot of controllers, actions and view models. Is there any cleaner way i can do the above without having to put this line above on every single controller action.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

薄凉少年不暖心 2024-10-07 14:53:01

您可以编写一个自定义操作过滤器属性,其中将在每个操作之后执行并设置基本模型的属性:

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();
        }
    }
}

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

处理此问题的另一种方法是使用 子操作 和没有基本视图模型。

You could write a custom action filter attribute which will execute after each action and set the property of the base model:

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();
        }
    }
}

Now all that's left is to decorate your base controller with this action filter.

Another way to handle this is to use child actions and not have a base view model.

日久见人心 2024-10-07 14:53:01

在你的 site.master 页面中,

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

如果你愿意的话,你可以在你的 homecontroller 中调用一个动作,让它返回 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 %>
<% }%> 

in your site.master page, call

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

you can call an action in your homecontroller if you want and just have it return a partial view of the html, in your case some menu links.

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

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

you can create a partial "MenuPartial.ascx"

<% foreach(var link in Model.MenuLinks) { %>
    <%: link.Name %>
<% }%> 
有木有妳兜一样 2024-10-07 14:53:01

我喜欢 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

I like justins example because it uses a MVC approach. I modified it so it works for MVC3 with razor.
Here's what I have in my _Layout.cshtml:

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

I created a LayoutController that has a menu action like this:

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

        return PartialView(viewModel);
    }
}

Which renders a partial view name Menu.cshtml

@model MenuViewModel
@if (Model.IsAdministrator)
{
   //render admin stuff
}
//render other items
静水深流 2024-10-07 14:53:01

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

然后您可以拥有一个 BaseController 类并将属性添加到 BaseController 中。

I think the best way to achieve your result without modifying all your controller action is to create a custom action filter that populate a property of your BaseModel with your menu links.

Then you could have a BaseController class and add the attribute to the BaseController.

可是我不能没有你 2024-10-07 14:53:01

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

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();

Create a factory class that give you the viewmodel already configured.

Class Factory{

  Repository _repository;

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

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

}

then in your controller you can use the Factory class instead of directly create an instance of viewModel

   ... your controller ...
   var factory = new Factory(_repository);
   var viewMolde = factory.GetViewModel();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文