Passar ViewData adicionais para uma exibição parcial fortemente tipada

174

Eu tenho uma exibição parcial fortemente tipada que usa uma ProductImage e, quando é renderizada, também gostaria de fornecer alguns ViewData adicionais que eu crio dinamicamente na página que contém. Como posso passar meu objeto fortemente digitado e meu ViewData personalizado para a exibição parcial com a chamada 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
fonte

Respostas:

251

RenderPartial usa outro parâmetro que é simplesmente um ViewDataDictionary. Você está quase lá, basta chamar assim:

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

Observe que isso substituirá os ViewData padrão que todas as suas outras Views possuem por padrão. Se você estiver adicionando algo ao ViewData, não será neste novo dicionário que você estará passando para a sua exibição parcial.

womp
fonte
2
Eu estou tentando fazer isso e está retornando "não é possível converter vazio em objeto".
programad
4
@programad Tente remover o @ do @ Html.RenderPartial (), esse problema foi corrigido para mim, mas eu estava chamando RenderPartial () em uma linha dentro de um bloco de código @ {}.
Danjarvis 11/06
5
Eu recomendo verificar a resposta do ctorx abaixo. Ele adiciona dados adicionais aos ViewData existentes.
raRaRa
162

Para estender o que o womp postou, você pode passar novos View Data, mantendo os View View existentes, se você usar a sobrecarga de construtor da seguinte ViewDataDictionarymaneira:

Html.RenderPartial(
      "ProductImageForm", 
       image, 
       new ViewDataDictionary(this.ViewData) { { "index", index } }
); 
ctorx
fonte
3
isso pode ser muito útil se você precisa para manter TemplateInfo.HtmlFieldPrefixno controle filho que será redefinir o contrário
Simon_Weaver
12
Esta é definitivamente a melhor solução. Perder o ViewData significa que você perde o ModelState e todas as validações. +1
Kevin Farrugia
Isso parece funcionar apenas se você não passar um TemplateInfo.HtmlFieldPrefix no seu ViewDataDictionary. Só posso passar uma variável como ilustrado na resposta ou passar um TemplateInfo.HtmlFieldPrefix, mas não 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
fonte
2
Essa parece ser a resposta mais completa (embora o .ToString () seja desnecessário).
Colin
9

Eu acho que isso deve funcionar não?

ViewData["currentIndex"] = index;
Joel Martinez
fonte
6
Embora essa não seja uma maneira muito forte de fazê-lo, ela me ajudou a descobrir como recuperar um valor de dados de exibição da resposta de Womp.
Mathias Lykkegaard Lorenzen
6

Crie outra classe que contenha sua classe fortemente tipada.

Adicione seus novos itens à turma e retorne-os à exibição.

Então, na visualização, garanta que você herda sua nova classe e altere os bits de código que agora estarão com erro. ou seja, as referências aos seus campos.

Espero que isto ajude. Caso contrário, avise-me e publicarei um código específico.

griegs
fonte
4

A maneira mais fácil de transmitir dados adicionais é adicioná-los aos ViewData existentes para a visualização, como observa @Joel Martinez. No entanto, se você não deseja poluir seu ViewData, o RenderPartial possui um método que aceita três argumentos, além da versão de dois argumentos exibida. O terceiro argumento é um ViewDataDictionary. Você pode construir um ViewDataDictionary separado apenas para o seu parcial contendo apenas os dados extras que você deseja transmitir.

tvanfosson
fonte
1

Isso também deve funcionar.

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

Html.RenderPartial(
      "ProductImageForm", 
       image, 
       this.ViewData
); 
MithunChopda
fonte
Obrigado! Isso é realmente útil quando você está estendendo o dicionário ViewData para parciais filhos, etc.
developius
1

Eu sei que este é um post antigo, mas me deparei com ele quando confrontado com um problema semelhante usando o núcleo 3.0, espero que ajude alguém.

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

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

Você pode usar a variável dinâmica ViewBag

ViewBag.AnotherValue = valueToView;
Jack1987
fonte