web-dev-qa-db-fra.com

Rendre une vue partielle avec un modèle dynamique dans le moteur de vue Razor et ASP.NET MVC 3

Lorsque j'essaie de rendre une vue partielle dont le type de modèle est spécifié comme suit:

@model dynamic

en utilisant le code suivant:

@{Html.RenderPartial("PartialView", Model.UserProfile);}

Je reçois l'exception suivante:

'System.Web.Mvc.HtmlHelper<dynamic>' has no applicable method named 'RenderPartial' but appears to have an extension method by that name. Extension methods cannot be dynamically dispatched. Consider casting the dynamic arguments or calling the extension method without the extension method syntax.

Cependant, le même code dans un fichier .aspx fonctionne parfaitement. Des pensées?

63
Diego

Vient de trouver la réponse, il apparaît que la vue où je plaçais le code RenderPartial avait un modèle dynamique et que, par conséquent, MVC ne pouvait pas choisir la méthode correcte à utiliser. La conversion du modèle dans l'appel RenderPartial vers le type correct a résolu le problème.

source: tilisation de Html.RenderPartial () dans les fichiers ascx

54
Diego

Au lieu de lancer le modèle dans l'appel RenderPartial, et puisque vous utilisez rasoir, vous pouvez modifier la première ligne de votre vue à partir de

@model dynamic

à

@model YourNamespace.YourModelType

Cela a l’avantage de travailler sur chaque @Html.Partial _ appel que vous avez dans la vue, et vous donne également intellisense pour les propriétés.

26
juan

Peut aussi être appelé comme

@Html.Partial("_PartialView", (ModelClass)View.Data)
17
Tom

Il y a une autre raison pour laquelle cela peut être lancé, même si vous n'utilisez pas dynamic/ExpandoObject. Si vous faites une boucle, comme ceci:

@foreach (var folder in ViewBag.RootFolder.ChildFolders.ToList())
{
    @Html.Partial("ContentFolderTreeViewItems", folder)
}

Dans ce cas, le "var" au lieu de la déclaration de type générera la même erreur, malgré le fait que RootFolder est du type "Dossier". En changeant le var en type réel, le problème disparaît.

@foreach (ContentFolder folder in ViewBag.RootFolder.ChildFolders.ToList())
{
    @Html.Partial("ContentFolderTreeViewItems", folder)
}
7
J Wynia

Voici un moyen de passer un objet dynamique à une vue (ou une vue partielle)

Ajoutez la classe suivante n’importe où dans votre solution (utilisez l’espace de noms System pour qu’il soit prêt à être utilisé sans ajouter de référence) -

    namespace System
    {
        public static class ExpandoHelper
        {
            public static ExpandoObject ToExpando(this object anonymousObject)
            {
                IDictionary<string, object> anonymousDictionary = HtmlHelper.AnonymousObjectToHtmlAttributes(anonymousObject);
                IDictionary<string, object> expando = new ExpandoObject();
                foreach (var item in anonymousDictionary)
                    expando.Add(item);
                return (ExpandoObject)expando;
            }

        }
    }

Lorsque vous envoyez le modèle à la vue, convertissez-le en Expando:

    return View(new {x=4, y=6}.ToExpando());

À votre santé

3

J'ai eu le même problème et dans mon cas c'est ce que j'ai fait

@Html.Partial("~/Views/Cabinets/_List.cshtml", (List<Shop>)ViewBag.cabinets)

et en vue partielle

@foreach (Shop cabinet in Model)
{
    //...
}
1
RousseauAlexandre

Je jouais avec le code C # et j’ai accidentellement trouvé la solution à votre problème, haha

Voici le code de la vue principale:

`@model dynamic 
 @Html.Partial("_Partial", Model as IDictionary<string, object>)`

Puis dans la vue partielle:

`@model dynamic 
 @if (Model != null) { 
   foreach (var item in Model) 
   { 
    <div>@item.text</div> 
   } 
  }`

Cela a fonctionné pour moi, j'espère que cela vous aidera aussi !!

0
Alan