web-dev-qa-db-fra.com

Passer des données à la page maître dans ASP.NET MVC

Quelle est votre façon de transmettre des données à la page maître (en utilisant ASP.NET MVC) sans enfreindre les règles MVC?

Personnellement, je préfère coder le contrôleur abstrait (contrôleur de base) ou la classe de base qui est passée à toutes les vues.

102
Łukasz Sowa

Si vous préférez que vos vues aient des classes de données de vue fortement typées, cela pourrait vous convenir. D'autres solutions sont probablement plus correctes mais c'est un bel équilibre entre design et praticité à mon humble avis.

La page maître prend une classe de données de vue fortement typée contenant uniquement les informations qui la concernent:

public class MasterViewData
{
    public ICollection<string> Navigation { get; set; }
}

Chaque vue utilisant cette page maître prend une classe de données de vue fortement typée contenant ses informations et dérivant des données de vue des pages maîtres:

public class IndexViewData : MasterViewData
{
    public string Name { get; set; }
    public float Price { get; set; }
}

Comme je ne veux pas que les contrôleurs individuels sachent quoi que ce soit sur la façon de rassembler les données des pages maîtres, j'encapsule cette logique dans une usine qui est transmise à chaque contrôleur:

public interface IViewDataFactory
{
    T Create<T>()
        where T : MasterViewData, new()
}

public class ProductController : Controller
{
    public ProductController(IViewDataFactory viewDataFactory)
    ...

    public ActionResult Index()
    {
        var viewData = viewDataFactory.Create<ProductViewData>();

        viewData.Name = "My product";
        viewData.Price = 9.95;

        return View("Index", viewData);
    }
}

L'héritage correspond bien au maître pour bien visualiser la relation, mais quand il s'agit de rendre des partiels/contrôles utilisateur, je vais composer leurs données de vue dans les pages, voir les données, par ex.

public class IndexViewData : MasterViewData
{
    public string Name { get; set; }
    public float Price { get; set; }
    public SubViewData SubViewData { get; set; }
}

<% Html.RenderPartial("Sub", Model.SubViewData); %>

Ceci n'est qu'un exemple de code et n'est pas destiné à être compilé tel quel. Conçu pour ASP.Net MVC 1.0.

77
Generic Error

Je préfère diviser les éléments basés sur les données de la vue principale en partiels et les rendre à l'aide de Html.RenderAction . Cela présente plusieurs avantages distincts par rapport à l'approche d'héritage du modèle de vue populaire:

  1. Les données de la vue principale sont complètement découplées des modèles de vue "standard". Il s'agit de la composition sur l'héritage et se traduit par un système plus faiblement couplé qui est plus facile à modifier.
  2. Les modèles de vue principale sont créés par une action de contrôleur complètement distincte. Les actions "régulières" n'ont pas besoin de s'inquiéter à ce sujet, et il n'y a pas besoin d'une fabrique de données de vue, ce qui semble trop compliqué à mon goût.
  3. S'il vous arrive d'utiliser un outil comme AutoMapper pour mapper votre domaine à vos modèles de vue, vous trouverez plus facile à configurer car vos modèles de vue ressembleront plus à vos modèles de domaine lorsqu'ils n'hériteront pas données de la vue principale.
  4. Avec des méthodes d'action distinctes pour les données de base, vous pouvez facilement appliquer la mise en cache de sortie à certaines régions de la page. Les vues principales contiennent généralement des données qui changent moins fréquemment que le contenu de la page principale.
59
Todd Menier

[~ # ~] modifier [~ # ~]

Erreur générique a fourni une meilleure réponse ci-dessous. Lisez-le s'il vous plaît!

Réponse originale

Microsoft a en fait publié une entrée sur la manière "officielle" pour gérer cela. Cela fournit une procédure pas à pas avec une explication de leur raisonnement.

En bref, ils recommandent d'utiliser une classe de contrôleur abstraite, mais voyez par vous-même.

20
Michael La Voie

Les contrôleurs abstraits sont une bonne idée et je n'ai pas trouvé de meilleur moyen. Je suis également curieux de voir ce que d'autres ont fait.

7
Ian P
3
David Negron

Je trouve qu'un parent commun pour tous les objets de modèle que vous passez à la vue est exceptionnellement utile.

De toute façon, il y aura toujours des propriétés de modèle communes entre les pages.

2
Matt Mitchell

Je pense qu'une autre bonne façon pourrait être de créer une interface pour la vue avec une propriété comme ParentView d'une interface, de sorte que vous pouvez l'utiliser à la fois pour les contrôles qui ont besoin d'une référence à la page (contrôle parent) et pour les vues principales auxquelles il faut accéder à partir de vues.

0
dimarzionist

Les autres solutions manquent d'élégance et prennent trop de temps. Je m'excuse d'avoir fait cette chose très triste et appauvrie presque un an plus tard:

<script runat="server" type="text/C#">
    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);
        MasterModel = SiteMasterViewData.Get(this.Context);
    }

    protected SiteMasterViewData MasterModel;
</script>

Donc, clairement, j'ai cette méthode statique Get () sur SiteMasterViewData qui renvoie SiteMasterViewData.

0
rasx

L'objet Request.Params est modifiable. Il est assez facile d'y ajouter des valeurs scalaires dans le cadre du cycle de traitement des demandes. Du point de vue de la vue, ces informations auraient pu être fournies dans QueryString ou FORM POST. hth

0
mtutty