2010-01-22 8 views
4

Plus j'utilise ASP.NET MVC, plus je l'aime. Cependant, dans le cas de l'affichage de données de modèle sur des pages maîtres, il semble y avoir plusieurs façons de le faire. Je ne suis pas sûr de la meilleure solution. Mon exemple serait un site de commerce où je veux afficher une liste de catégories de produits sur chaque page et montrer également l'état du panier des visiteurs. Dans les formulaires Web asp.net, j'utilise généralement les contrôles utilisateur en effectuant chacun leur propre liaison de données pour récupérer les données requises.ASP.NET MVC Master Page Données

Dans MVC, toutes les données doivent être transmises par le contrôleur.

Donc, en ce qui concerne les catégories, la solution la plus simple semble être de transmettre ceci dans Voir les données dans l'action du contrôleur:

ViewData["Categories"] = _service.GetCategories(); 

Cependant, ce faisant pour chaque action est pas très sec pour la suite this article j'ai créé un contrôleur de base qui ajoute les données nécessaires à mon ViewData:

public class AppController : Controller 
{ 
    IAppService _service; 

    public AppController() { } 
    public AppController(IAppService appService) 
    { 
     _service = appService; 
     SetSiteData(); 
    } 

    private void SetSiteData() 
    { 
     ViewData["Categories"] = _service.GetCategories(); 
    } 
} 

J'ai ensuite créé une extension pour ViewMasterPage:

 public static void RenderCategoryList(this ViewMasterPage pg) { 
     pg.Html.RenderPartial("CategoryList", pg.ViewData["Categories"]); 
    } 

Et dans mon MasterPage:

 <div> 
     <%this.RenderCategoryList(); %> 
    </div> 

Cela semble être une approche tout à fait propre. Cependant, est-ce le meilleur moyen que j'ai vu aussi des suggestions de créer un ViewModel pour votre MasterPage. Je pourrais voir que peut-être que vos données ViewModel se développent, cela peut être une meilleure solution.

En ce qui concerne l'état du chariot, je suppose que je ferais quelque chose de similaire mais je ne suis pas sûr que RenderAction serait plus approprié (When to use RenderAction vs RenderPartial with ASP.NET MVC). Merci, Ben

Répondre

7

Cela fonctionne, bien que ce n'est pas la façon dont je le ferais pour 2 raisons:

  1. Je n'aime pas coller les données dans ViewState depuis que vous lancez essentiellement comme objet
  2. en exigeant un contrôleur de base vous limitez la fonctionnalité aux contrôleurs qui héritent de cette BaseController (qui pourrait ne pas être un problème si)

Je pense que ce serait une utilisation parfaite de RenderAction (partie du projet MvcFutures). Cette aide peut être utilisée pour afficher une action sur un autre contrôleur. Donc, vous pourriez avoir un ProductController avec une action ListCategories, vous pouvez simplement faire quelque chose comme:

<% Html.RenderAction<ProductController>(x => x.ListCategories()); %> 

ListCategories appellerait

_service.GetCategories(); 

et pourrait coller les informations dans son propre modèle. Alors il passerait ce modèle à la vue serait une page partielle.

+1

+1 pour RenderAction, c'est presque une solution parfaite, après que MVC2 soit sorti et que vous puissiez mettre en cache les résultats de RenderAction, ce sera parfait. – mxmissile

+0

Dois-je faire quelque chose pour utiliser l'appel RenderAction fortement typé que vous utilisez ci-dessus? J'utilise mvc 2.0 preview et ne semble pas pouvoir construire la méthode RenderAction de cette façon. –

2

Merci - RenderAction était parfait pour le travail.J'ai reçu plus d'informations de here.

pour le bénéfice des autres, voici un exemple de la façon dont je suis délivrer en sortie le statut de panier:

Action:

[ChildActionOnly] 
    public ActionResult CartStatus() 
    { 
     return PartialView(_service.GetCartSummary()); 
    } 

Vue partielle (lié à Models.Cart)

<div class="cartSummary"> 
<%if (Model.HasItems) { %> 
    Cart Items: <%=Model.Items.Count() %> | Total: <%=Model.TotalItems %> 
<%} else {%> 
    Your cart is empty. Please buy stuff! 
<%} %> 

Méthode auxiliaire pour maître Page:

public static void RenderCartStatus(this ViewMasterPage pg) { 
     pg.Html.RenderAction("CartStatus", "Catalog", null); 
    } 

Et enfin page maître:

<%this.RenderCartStatus(); %> 

Merci pour le conseil.

+0

en essayant de mettre en œuvre ces solutions, mais je ne peux pas imaginer où créer la méthode d'assistance pour la page maître? Est-ce que je crée un autre fichier de classe C# quelque part? – JBeckton

+0

@JBeckon - oui vous pouvez créer une classe statique pour contenir ces extensions. Assurez-vous simplement de référencer l'espace de noms dans votre vue ou dans web.config. –