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

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.


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

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>

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;

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.


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.


1

Isso também deve funcionar.

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

Html.RenderPartial(
      "ProductImageForm", 
       image, 
       this.ViewData
); 

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" />

0

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

ViewBag.AnotherValue = valueToView;
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.