2010-10-28 20 views
60

Cuando intento para hacer una vista parcial cuyo tipo de modelo se especifica como:Render vista parcial con el modelo dinámico en el motor de vista Maquinilla de afeitar y ASP.NET MVC 3

@model dynamic 

utilizando el siguiente código:

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

tengo la siguiente excepción:

'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. 

Sin embargo, el mismo código en un archivo .aspx funciona a la perfección. ¿Alguna idea?

Respuesta

53

Acabo de encontrar la respuesta, parece que la vista donde estaba colocando el código de RenderPartial tenía un modelo dinámico, y por lo tanto, MVC no pudo elegir el método correcto para usar. Lanzar el modelo en la llamada de RenderPartial al tipo correcto solucionó el problema.

fuente: Using Html.RenderPartial() in ascx files

+12

derecho, la razón principal de esto no funciona es que C# no admite llamar a un método de extensión (que es lo que 'Html.RenderPartial()' es) cuando cualquiera de los argumentos es de tipo dinámico. Debe invocar el método de extensión estáticamente o convertir el argumento a un tipo no dinámico. – Eilon

16

también puede ser llamado como

@Html.Partial("_PartialView", (ModelClass)View.Data) 
+0

Esto tiene la desventaja de que genera un 'MvcHtmlString' temporal (y potencialmente grande) sobre la marcha, en lugar de simplemente escribir en la salida directamente. –

+0

¿Esto no funcionará con RenderPartial? – ajbeaven

+0

Descubrí que necesitaba lanzar mi modelo así, aunque mi modelo no fue declarado 'dinámico '. Probablemente fue porque mi modelo era una lista. – levininja

25

En lugar de vaciar el modelo de la llamada renderPartial, y desde que está utilizando la maquinilla de afeitar, puede modificar la primera línea en la vista de

@model dynamic 

a

@model YourNamespace.YourModelType 

Esto tiene la ventaja de trabajar en cada llamada @Html.Partial que tiene en la vista, y también le da intellisense para las propiedades.

+5

+1 como me parece más sensato que la sugerencia de Diego, por las razones mencionadas anteriormente. es decir, si sabes de qué tipo estás tratando, ¡entonces trata con ese tipo! – MemeDeveloper

+0

no tiene sentido. Si quiero usar un modelo dinámico, me gustaría que los ayudantes me ayuden. El modelo dinámico en la mayoría de los casos es más simple y más productivo ya que no tiene que declarar las clases. – ema

+2

@ema: el uso de modelos dinámicos también conduce a un código más descuidado y mal pensado. ViewModels es casi siempre una mejor idea que los modelos dinámicos. ¡A menos que quiera encontrar errores de compilación en tiempo de ejecución! –

3

Aquí está una manera de pasar un objeto dinámico a una vista (o vista parcial)

Añadir la siguiente clase en cualquier parte de su solución (espacio de nombres de uso del sistema, por lo que su lista para usar sin tener que añadir ningún referencias) -

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

     } 
    } 

al enviar el modelo a la vista, convertirla en Expansión:

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

Saludos

7

Hay otra razón por la que se puede lanzar, incluso si no está utilizando Dynamic/ExpandoObject. Si usted está haciendo un bucle, como esto:

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

En ese caso, el "var" en lugar de la declaración de tipo tirarán el mismo error, a pesar de que RootFolder es de tipo carpeta" Cambiando el. var al tipo real, el problema desaparece.

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

que tenían el mismo problema & en mi caso esto es lo que hice

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

y en vista parcial

@foreach (Shop cabinet in Model) 
{ 
    //... 
} 
Cuestiones relacionadas