Pase datos de vista adicionales a una vista parcial fuertemente tipada

174

Tengo una vista parcial fuertemente tipada que toma una imagen de producto y cuando se renderiza también me gustaría proporcionarle algunos datos de vista adicionales que creo dinámicamente en la página que lo contiene. ¿Cómo puedo pasar mi objeto fuertemente tipado y mi ViewData personalizado a la vista parcial con la llamada RenderPartial?

var index = 0;
foreach (var image in Model.Images.OrderBy(p => p.Order))
{
  Html.RenderPartial("ProductImageForm", image); // < Pass 'index' to partial
  index++;
}
Nathan Taylor
fuente

Respuestas:

251

RenderPartial toma otro parámetro que es simplemente un ViewDataDictionary. Ya casi estás allí, solo llámalo así:

Html.RenderPartial(
      "ProductImageForm", 
       image, 
       new ViewDataDictionary { { "index", index } }
); 

Tenga en cuenta que esto anulará los ViewData predeterminados que todas sus otras Vistas tienen por defecto. Si está agregando algo a ViewData, no estará en este nuevo diccionario que está pasando a su vista parcial.

womp
fuente
2
Estoy tratando de hacer esto y está devolviendo "no se puede convertir vacío a objeto".
programado el
44
@programad Intente eliminar el @ de @ Html.RenderPartial (), esto solucionó ese problema para mí, pero estaba llamando a RenderPartial () en una línea dentro de un bloque de código @ {}.
danjarvis
55
Recomiendo revisar la respuesta de ctorx a continuación. Agrega datos adicionales a los ViewData existentes.
raRaRa
162

Para ampliar qué womp publicado, puede pasar nuevos datos de vista mientras conserva los datos de vista existentes si usa la sobrecarga del constructor de la ViewDataDictionarymisma manera:

Html.RenderPartial(
      "ProductImageForm", 
       image, 
       new ViewDataDictionary(this.ViewData) { { "index", index } }
); 
ctorx
fuente
3
esto puede ser muy útil si se necesita para retener TemplateInfo.HtmlFieldPrefixen el control secundario que se restablezca lo contrario
Simon_Weaver
12
Esta es definitivamente la mejor solución. Perder ViewData significa que pierde ModelState y todas las validaciones. +1
Kevin Farrugia
Esto parece funcionar solo si no pasa un TemplateInfo.HtmlFieldPrefix en su ViewDataDictionary. Solo puedo pasar una variable como se ilustra en la respuesta, o pasar un TemplateInfo.HtmlFieldPrefix pero no ambos.
Ferox
45
@Html.Partial("_Header", new ViewDataDictionary { { "HeaderName", "User Management" }, { "TitleName", "List Of Users" } })
or
@{Html.RenderPartial("_Header", new ViewDataDictionary { { "HeaderName", "User Management" }, { "TitleName", "List Of Users" } });}

Página parcial (_Header):

<div class="row titleBlock">
    <h1>@ViewData["HeaderName"].ToString()</h1>
    <h5>@ViewData["TitleName"].ToString()</h5>
</div>
muthuvel
fuente
2
Esta parece ser la respuesta más completa (aunque .ToString () es innecesario).
Colin
9

Creo que esto debería funcionar no?

ViewData["currentIndex"] = index;
Joel Martinez
fuente
66
Si bien esta no es una forma muy sólida de hacerlo, me ayudó a descubrir cómo recuperar un valor de datos de vista de la respuesta de Womp.
Mathias Lykkegaard Lorenzen
6

Cree otra clase que contenga su clase fuertemente tipada.

Agregue sus cosas nuevas a la clase y devuélvalas a la vista.

Luego, en la vista, asegúrese de heredar su nueva clase y cambie los bits de código que ahora estarán en error. a saber, las referencias a sus campos.

Espero que esto ayude. Si no es así, avíseme y publicaré un código específico.

quejas
fuente
4

La forma más fácil de pasar datos adicionales es agregar los datos a los ViewData existentes para la vista como señala @Joel Martinez. Sin embargo, si no desea contaminar su ViewData, RenderPartial tiene un método que toma tres argumentos, así como la versión de dos argumentos que muestra. El tercer argumento es un ViewDataDictionary. Puede construir un ViewDataDictionary separado solo para su parcial que contenga solo los datos adicionales que desea pasar.

tvanfosson
fuente
1

Esto también debería funcionar.

this.ViewData.Add("index", index);

Html.RenderPartial(
      "ProductImageForm", 
       image, 
       this.ViewData
); 
MithunChopda
fuente
¡Gracias! Esto es realmente útil cuando está extendiendo el diccionario ViewData para parciales secundarios, etc.
desarrollo
1

Sé que esta es una publicación antigua, pero la encontré cuando tuve un problema similar con Core 3.0, espero que ayude a alguien.

@{
Layout = null;
ViewData["SampleString"] = "some string need in the partial";
}

<partial name="_Partial" for="PartialViewModel" view-data="ViewData" />
Drytin
fuente
0

Puede usar la variable dinámica ViewBag

ViewBag.AnotherValue = valueToView;
Jack1987
fuente