In asp.net-mvc, what is the best way to have a Base ViewModel to display dynamic content on a Site.Master page

I have an asp.net-mvc website and there is information that I want to display on every page. I created a class called BaseViewModel, and each of the viewModel classes inherits from BaseViewModel. The View.Master view is directly bound to the BaseViewModel.

Currently, the base class has one property called MenuLinks.

The menulinks property is taken from the database call, so with every action of the controller that launches the ViewModel, I add a new line:

viewModel.MenuLinks = _repository.GetMenuLinks(); 

I have many controllers, actions, and view models. Is there any cleaner way that I can do above without putting this line above on every controller action.

+2
source share
5 answers

You can write your own action filter attribute that will be executed 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 remains is to decorate your base controller with this action filter.

Another way to handle this is to use child actions and not have a basic presentation model.

+11
source

on the .master website page, call

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

you can call an action in your homecontroller if you want, and just return a partial html view to it, 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 %> <% }%> 
+2
source

I like the justins example because it uses the MVC approach. I changed it to work on MVC3 with a razor. Here is 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); } } 

What is a partial view name Menu.cshtml

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

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

Then you can have the BaseController class and add an attribute to the BaseController.

0
source

Create a factory class that will give you an already configured view model.

 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 creating an instance of viewModel

  ... your controller ... var factory = new Factory(_repository); var viewMolde = factory.GetViewModel(); 
0
source

Source: https://habr.com/ru/post/1344978/


All Articles