2010-11-06 1 views
2

J'ai un site asp.net-mvc et il y a des informations que je veux montrer sur chaque page. J'ai créé une classe appelée BaseViewModel et chacune des classes viewModel hérite de BaseViewModel. La vue Site.Master se lie directement au BaseViewModel.dans asp.net-mvc, quelle est la meilleure façon d'avoir un ViewModel de base pour afficher le contenu dynamique sur le Site.Master page

La classe de base a maintenant une propriété appelée MenuLinks.

La propriété menulinks se peuplé d'un appel de base de données ainsi de suite chaque action du contrôleur qui est instatiating un ViewModel je suis une nouvelle gamme:

viewModel.MenuLinks = _repository.GetMenuLinks(); 

j'ai beaucoup de contrôleurs, des actions et des modèles de vue. Y at-il une façon plus propre que je peux faire ce qui précède sans avoir à mettre cette ligne ci-dessus sur chaque action de contrôleur unique.

+0

double possible de [Comment utiliser un ViewModel de base dans Asp.net MVC 2] (http://stackoverflow.com/questions/2751225/how-to-use-a-base-viewmodel-in -asp-net-mvc-2) - Dupe est la deuxième question connexe lorsque vous avez posé cette question. – jfar

Répondre

11

Vous pouvez écrire une coutume action filter attribute qui exécutera après chaque action et définir la propriété du modèle de base:

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

Maintenant tout ce qui reste est de décorer votre contrôleur de base avec ce filtre d'action.

Une autre façon de gérer cela est d'utiliser child actions et ne pas avoir un modèle de vue de base.

+1

+1 pour me battre à l'heure :) – Lorenzo

+0

J'aime ça, je stocke ce code :) –

+0

Composition> Héritage. Je fais exactement la même chose mais avec ViewData []. (Mais seulement pour les choses de la page maîtresse sinon il va dans le modèle.) – Ryan

2

dans votre page Site.master, appelez

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

vous pouvez appeler une action dans votre HomeController si vous voulez et avez juste revenir une vue partielle du html, dans votre cas des liens de menu.

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

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

vous pouvez créer une partie "MenuPartial.ascx"

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

Je pense que la meilleure façon de réaliser votre résultat sans modifier toute l'action de votre contrôleur est de créer un filtre d'action personnalisé qui remplit une propriété de votre BaseModel avec vos liens de menu.

Ensuite, vous pourriez avoir une classe BaseController et ajouter l'attribut à BaseController.

0

Créez une classe de fabrique qui vous donne le modèle de vue déjà configuré.

Class Factory{ 

    Repository _repository; 

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

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

} 

puis dans votre contrôleur, vous pouvez utiliser la classe Factory au lieu de créer directement une instance de viewmodel

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

J'aime justins exemple parce qu'il utilise une approche MVC. Je l'ai modifié pour que ça fonctionne pour MVC3 avec le rasoir. Voici ce que j'ai dans mon _Layout.cshtml:

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

J'ai créé un LayoutController qui a une action de menu comme ceci:

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

     return PartialView(viewModel); 
    } 
} 

Ce qui rend un menu nom de la vue partielle.cshtml

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