¿Cómo puedo pasar parámetros a una vista parcial en mvc 4?

152

Tengo un enlace como este:

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

y cuando hago clic en esto, llamará a esta página parcial:

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

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

    }
}

Página parcial _Perfil contiene:

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

Ejemplo:

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

Mi duda es que, ¿cómo puedo pasar este "Id" a la parte model.parameter ?

Mis controladores son:

 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
fuente
2
No lo entiendo Quizás si agrega su controlador y acción podría ayudar, pero como está escrito ahora, no entiendo su pregunta.
Liam
ver acerca de Extensión parcial en msdn
Grundy

Respuestas:

346

Su pregunta es difícil de entender, pero si estoy entendiendo la esencia, simplemente tiene algún valor en su vista principal al que desea acceder en una representación parcial en esa vista.

Si solo representa un parcial con solo el nombre parcial:

@Html.Partial("_SomePartial")

En realidad, pasará su modelo como un parámetro implícito, igual que si llamara:

@Html.Partial("_SomePartial", Model)

Ahora, para que su parcial pueda usar esto, también necesita tener un modelo definido, por ejemplo:

@model Namespace.To.Your.Model

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

Alternativamente, si está tratando con un valor que no está en el modelo de su vista (está en ViewBag o un valor generado en la vista de alguna manera, entonces puede pasar un ViewDataDictionary

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

Y entonces:

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

Al igual que con el modelo, Razor pasará implícitamente su vista parcial de ViewDataforma predeterminada, por lo que si tenía ViewBag.Iden su vista, puede hacer referencia a lo mismo en su parcial.

Chris Pratt
fuente
44
Si hace que su modelo principal implemente una interfaz, puede hacer que la vista parcial use esa interfaz como modelo. Entonces puede obtener mucha reutilización.
Jess
@ChrisPratt Respuesta muy explicativa como siempre :) Votado +
Murat Yıldız
66
Tuve que usar @Html.Partial("_SomePartial", new Microsoft.AspNet.Mvc.ViewFeatures.ViewDataDictionary(this.ViewData) { { "id", someInteger } });para que esto funcionara para mí. Estoy usando VS2015 DNX 4.5.1 si alguien más tiene este mismo problema.
MikeTeeVee
46

Uno de los métodos más cortos que encontré para un valor único mientras me buscaba es simplemente pasar una sola cadena y establecer una cadena como modelo a la vista de esta manera.

En su lado de llamada parcial

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

Y luego vinculando el modelo con Vista parcial como esta

@model string

y el uso de su valor en Vista parcial como este

@Model

También puedes jugar con otros tipos de datos como array, int o tipos de datos más complejos como IDictionary u otra cosa.

Espero eso ayude,

Osama Sheikh
fuente
44
Esto es genial! Exactamente lo que quería. Gracias.
Gautam Jain
Mi parcial no necesitaba mi modelo, pero necesitaba preservar todas las cosas de ViewData ModelState ... esto funcionó. En mi vista parcial, todavía puedo acceder a ViewContext.ViewData.ModelState.ContainsKey (@ Model.ToString ())
da_jokker
Esto sigue arrojando una NullReferenceExceptionreferencia de objeto no establecida en una instancia de un objeto, está diciendo que Modeles nulo. ¿Algunas ideas?
facepalm42
15

Aquí hay un método de extensión que convertirá un objeto en 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;
}

Luego puede usarlo en su vista así:

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

Lo cual es mucho mejor que la new ViewDataDictionary { { "Property1", "Value1" } , { "Property2", "Value2" }}sintaxis.

Luego, en su vista parcial, puede usar ViewBagpara acceder a las propiedades desde un objeto dinámico en lugar de propiedades indexadas, por ejemplo

<p>@ViewBag.Property1</p>
<p>@ViewBag.Property2</p>
Chris Haines
fuente
¿Dónde debo poner este ToViewDataDictionarymétodo estático? En todas partes donde trato de ponerlo me sale algún tipo de error del compilador.
Csaba Toth
2
@CsabaToth este es un método de extensión. Simplemente colóquelo en una clase estática y luego haga referencia a esa clase en su vista.
Chris Haines
3

Para Asp.Net core es mejor usar

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

Así por ejemplo

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