193 votes

Le rendu partiel avec un modèle nul se voit passer le mauvais type.

J'ai une page :

<%@ Page Inherits="System.Web.Mvc.View<DTOSearchResults>" %>

Et dessus, le texte suivant :

<% Html.RenderPartial("TaskList", Model.Tasks); %>

Voici l'objet DTO :

public class DTOSearchResults
{
    public string SearchTerm { get; set; }
    public IEnumerable<Task> Tasks { get; set; }

et voici le partiel :

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<IEnumerable<Task>>" %>

Lorsque Model.Tasks n'est pas nul, tout fonctionne bien. Cependant, lorsqu'il est nul, j'obtiens :

L'élément de modèle passé dans le dictionnaire est de type 'DTOSearchResults' mais ce dictionnaire requiert un élément de modèle de type System.Collections.Generic.IEnumerable`1[Task]'.

Je me suis dit qu'il ne devait pas savoir quelle surcharge utiliser, alors j'ai fait ceci (voir ci-dessous) pour être explicite, mais j'ai toujours le même problème !

<% Html.RenderPartial("TaskList", (object)Model.Tasks, null); %>

Je sais que je peux contourner ce problème en vérifiant la présence de null, ou même en ne passant pas null, mais ce n'est pas le problème. Pourquoi cela se produit-il ?

341voto

meandmycode Points 9475

Andrew Je pense que le problème que vous rencontrez est le résultat de la méthode RenderPartial qui utilise le modèle de la (vue) appelante pour la vue partielle lorsque le modèle que vous passez est nul vous pouvez contourner ce comportement étrange en faisant :

<% Html.RenderPartial("TaskList", Model.Tasks, new ViewDataDictionary()); %>

Est-ce que ça aide ?

46voto

configurator Points 15594

La réponse de @myandmycode est bonne, mais une réponse légèrement plus courte serait la suivante

<% Html.RenderPartial("TaskList", new ViewDataDictionary(Model.Tasks)); %>

Cela fonctionne parce que le ViewDataDictionary est la chose qui contient le modèle, et il peut accepter un modèle comme paramètre de construction. Cela transmet essentiellement un dictionnaire de données de vue "entier", qui ne contient bien sûr que le modèle éventuellement nul.

24voto

Zack Points 89

Il semble que lorsque la propriété du modèle que vous transmettez est nulle, MVC revient intentionnellement au modèle "parent". Apparemment, le moteur MVC interprète une valeur de modèle nulle comme une intention d'utiliser le modèle précédent.

Un peu plus de détails ici : ASP.NET MVC, vues fortement typées, problème de paramètres de vue partiels

20voto

Fran P Points 51

Si vous ne voulez pas perdre vos ViewData précédentes dans la vue partielle, vous pouvez essayer :

<% Html.RenderPartial("TaskList", Model.Tasks, new ViewDataDictionary(ViewData){Model = null});%>

12voto

Colin Breame Points 179

Une solution serait de créer un HtmlHelper comme ceci :

public static MvcHtmlString Partial<T>(this HtmlHelper htmlHelper, string partialViewName, T model)
{
    ViewDataDictionary viewData = new ViewDataDictionary(htmlHelper.ViewData)
    {
        Model = model
    };
    return PartialExtensions.Partial(htmlHelper, partialViewName, model, viewData);
}

El Partial<T>(...) correspondaient avant le Partial(...) si pratique et aucune erreur d'ambiguïté lors de la compilation.

Personnellement, j'ai du mal à comprendre ce comportement - il semble difficile d'imaginer que ce soit un choix de conception ?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X