Como posso passar parâmetros para uma vista parcial no mvc 4

152

Eu tenho um link como este:

 <a href='Member/MemberHome/Profile/Id'><span>Profile</span></a>

e quando eu clicar nele, ele chamará esta página parcial:

 @{
    switch ((string)ViewBag.Details)
    {

        case "Profile":
        {
           @Html.Partial("_Profile"); break;
        }

    }
}

A página parcial _Profile contém:

Html.Action("Action", "Controller", model.Paramter) 

Exemplo:

@Html.Action("MemberProfile", "Member", new { id=1 })   // id is always changing

A minha dúvida é que como posso passar esse "Id" para a parte model.parameter ?

Meus controladores são:

 public ActionResult MemberHome(string id)
    {
        ViewBag.Details = id;
        return View();
    }
  public ActionResult MemberProfile(int id = 0)
    {
        MemberData md = new Member().GetMemberProfile(id);
        return PartialView("_ProfilePage",md);
    }
neel
fonte
2
Eu não entendo. Talvez se você adicionar seu controlador e ação, isso pode ajudar, mas como está escrito agora, não entendo sua pergunta.
Liam
veja sobre Extensão parcial no msdn
Grundy

Respostas:

346

Sua pergunta é difícil de entender, mas se eu estou entendendo a essência, você simplesmente tem algum valor em sua visão principal que deseja acessar de forma parcial nessa visão.

Se você apenas tornar um parcial apenas com o nome parcial:

@Html.Partial("_SomePartial")

Na verdade, ele passará seu modelo como um parâmetro implícito, o mesmo que se você chamasse:

@Html.Partial("_SomePartial", Model)

Agora, para que seu parcial possa realmente usar isso, ele também precisa ter um modelo definido, por exemplo:

@model Namespace.To.Your.Model

@Html.Action("MemberProfile", "Member", new { id = Model.Id })

Como alternativa, se você estiver lidando com um valor que não está no modelo da sua visualização (está no ViewBag ou um valor gerado na própria visualização de alguma forma, poderá passar um ViewDataDictionary

@Html.Partial("_SomePartial", new ViewDataDictionary { { "id", someInteger } });

E depois:

@Html.Action("MemberProfile", "Member", new { id = ViewData["id"] })

Assim como no modelo, o Razor passa implicitamente a sua parcial pela visualização ViewDatapor padrão; portanto, se você tiver ViewBag.Idna sua visualização, poderá fazer referência à mesma coisa na sua parcial.

Chris Pratt
fonte
4
Se você fizer seu modelo principal implementar uma interface, poderá fazer com que a vista parcial use essa interface como modelo. Então você pode obter muito reuso com isso.
Jess
@ChrisPratt Resposta muito explicativa como sempre :) Votou +
Murat Yıldız
6
Eu tive que usar @Html.Partial("_SomePartial", new Microsoft.AspNet.Mvc.ViewFeatures.ViewDataDictionary(this.ViewData) { { "id", someInteger } });para isso funcionar para mim. Estou usando o VS2015 DNX 4.5.1 se mais alguém tiver esse mesmo problema.
MikeTeeVee
46

Um dos métodos mais curtos que encontrei para um valor único enquanto procurava por mim mesmo é apenas passar uma única string e defini-la como modelo em vista como esta.

No seu lado de chamada parcial

@Html.Partial("ParitalAction", "String data to pass to partial")

E depois vincular o modelo à Vista Parcial como esta

@model string

e usando seu valor na Vista Parcial como esta

@Model

Você também pode jogar com outros tipos de dados, como array, int ou tipos de dados mais complexos, como IDictionary ou outra coisa.

Espero que ajude,

Osama Sheikh
fonte
4
Isso é legal! Exatamente o que eu queria. Obrigado.
Gautam Jain 22/11
Minha parcial não precisava do meu modelo, mas eu precisava preservar todas as coisas do ViewData ModelState. Isso fez o truque. Na minha visão parcial, ainda posso acesso ViewContext.ViewData.ModelState.ContainsKey (@ Model.ToString ())
da_jokker
Isso continua lançando uma NullReferenceExceptionreferência de objeto não definida para uma instância de um objeto, está dizendo que Modelé nulo. Alguma ideia?
precisa saber é o seguinte
15

Aqui está um método de extensão que converterá um objeto em um ViewDataDictionary.

public static ViewDataDictionary ToViewDataDictionary(this object values)
{
    var dictionary = new ViewDataDictionary();
    foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(values))
    {
        dictionary.Add(property.Name, property.GetValue(values));
    }
    return dictionary;
}

Você pode usá-lo em sua exibição da seguinte maneira:

@Html.Partial("_MyPartial", new
{
    Property1 = "Value1",
    Property2 = "Value2"
}.ToViewDataDictionary())

O que é muito melhor do que a new ViewDataDictionary { { "Property1", "Value1" } , { "Property2", "Value2" }}sintaxe.

Em sua visão parcial, você pode usar ViewBagpara acessar as propriedades de um objeto dinâmico, em vez de propriedades indexadas, por exemplo

<p>@ViewBag.Property1</p>
<p>@ViewBag.Property2</p>
Chris Haines
fonte
Onde devo colocar esse ToViewDataDictionarymétodo estático? Em todo lugar que tento colocar, recebo algum tipo de erro do compilador.
Csaba Toth
2
@CsabaToth este é um método de extensão. Apenas coloque-o em uma classe estática e faça referência a essa classe na sua exibição.
21718 Chris Haines #
3

Para o núcleo do Asp.Net, é melhor usar

<partial name="_MyPartialView" model="MyModel" />

Então por exemplo

@foreach (var item in Model)
{
   <partial name="_MyItemView" model="item" />
}
Gerard
fonte