2012-05-20 16 views
9

por lo que quiero para crear una vista reutilizable para la edición de una dirección, número de teléfono, etc.MVC4 Vista parcial no cargar los valores en el modelo de "contenedor" en segundo palo

I fijó un modelo de contenedor que contiene toda la Modelos necesarios. crea una vista parcial de manejar la parte de dirección de l e forma

Pero cuando se publica de nuevo al controlador, los datos del cliente está allí desde la página principal, pero nada de las vistas parciales no está allí (usando MVC4/Razor)

contenedor de modelos

public class CustomerViewModel { 
    public Customer CustomerData { get; set; } 
    public Address MainAddress { get; set; } 
    public Address ShippingAddress { get; set; } 
    public Phone MainPhone { get; set; } 
    public Phone Fax { get; set; } 
} 

controlador:

public ActionResult Edit(int id = 0) { 
    CustomerViewModel model = new CustomerViewModel(); 
    model.CustomerData = Customer.FetchById(id); 
    if (model.CustomerData == null) return HttpNotFound(); 

    //... load addresses, phones 

    return View(model); 
} 

[HttpPost] 
public ActionResult Edit(CustomerViewModel model) { 
    if (ModelState.IsValid) { 
     ///... save everything here - model has CustomerData, but nothing else 
    } 

    return View(model); 
} 

Vista principal:

@model ProjectName.WebSite.Models.CustomerViewModel 

..... 

@using (Html.BeginForm()) { 
    @Html.ValidationSummary(true) 

    <fieldset> 
     <legend>Customer</legend> 
     @Html.HiddenFor(model => model.ModelCustomer.CustomerId) 

     <div class="editor-label"> 
      @Html.LabelFor(model => model.ModelCustomer.CompanyName) 
     </div> 
     <div class="editor-field"> 
      @Html.EditorFor(model => model.ModelCustomer.CompanyName) 
      @Html.ValidationMessageFor(model => model.ModelCustomer.CompanyName) 
     </div> 

     ...   

     @Html.Partial("Address", Model.MainAddress, new ViewDataDictionary { 
      TemplateInfo = new System.Web.Mvc.TemplateInfo { HtmlFieldPrefix = "Main" } 
     }) 

     ...   

     <p> 
      <input type="submit" value="Save" /> 
     </p> 
    </fieldset> 
} 
..... 

Dirección Vista parcial:

@model ProjectName.Business.Address 

<fieldset style="margin-top: 20px;"> 
    <legend>@(ViewData["label"] ?? "Address")</legend> 

    @Html.HiddenFor(model => model.AddressId) 

    <div class="editor-label"> 
     @Html.LabelFor(model => model.Street) 
    </div> 
    <div class="editor-field"> 
     @Html.EditorFor(model => model.Street) 
     @Html.ValidationMessageFor(model => model.Street) 
    </div> 
    ... 
</fieldset> 

¿Qué estoy haciendo mal aquí - ¿por qué no puedo obtener el modelo de población de las vistas parciales?

+1

Si su respuesta a esta pregunta a sí mismo, facilite una respuesta (abajo) y lo aceptan así que la pregunta se marca contestada. – kingdango

+0

@Nayt, kingdango tiene razón. Mueva la parte de su pregunta marcada como "SOLUCIONADO" como una nueva respuesta a continuación. Después de hacerlo, márcalo como la respuesta aceptada. Un buen resultado de hacerlo es que a otros también les puede resultar útil su respuesta; si lo hacen, votarán positivamente su respuesta, que es una de las cosas divertidas de participar en este sitio. –

+0

Creo que será mejor que utilices un EditorTemplate para el tipo de Dirección aquí. Esto evitaría muchos problemas al mantener su código en el futuro. –

Respuesta

12

¡Solucionado! ¡Lo descubrí! No pude dormir, ¡y me tropecé con eso!

En la Vista debe asegurarse de que HtmlFieldPrefix usa el mismo nombre que en su clase de modelo compuesta, así que desde que denominé las dos direcciones como "MainAddress" y "ShippingAddress" - solo tengo que asegurarme de que el mismo nombre se utiliza al configurar el parcial:

@Html.Partial("Address", Model.MainAddress, new ViewDataDictionary(Html.ViewDataContainer.ViewData) { 
    TemplateInfo = new System.Web.Mvc.TemplateInfo { HtmlFieldPrefix = "MainAddress" } 
}) 

@Html.Partial("Address", Model.ShippingAddress, new ViewDataDictionary(Html.ViewDataContainer.ViewData) { 
    TemplateInfo = new System.Web.Mvc.TemplateInfo { HtmlFieldPrefix = "ShippingAddress" } 
}) 
+0

Tuve el problema exacto y tropecé con esta publicación antes de que yo mismo estuviera a punto de hacer una pregunta similar. Estaba haciendo todo lo que era, excepto que en mi @ Html.Partial ("Dirección", Model.ShippingAddress) no estaba usando el tercer parámetro de entrada ViewDataDictionary, y estaba teniendo el mismo problema que tenía en la devolución. ¿Por qué esta porción de ViewDataDictionary es "obligatoria"? En mi caso, solo tengo 1 tipo de dirección, no múltiples tipos como usted, así que solo decir "Model.MainAddress" debería ser suficiente en mi caso, me imagino. (Sí, todo funcionó bien al incluir este tercer parámetro de entrada). –

+0

Aunque solo tenga una dirección, el 3er parámetro aún le dice al código qué propiedad de su vista contiene la dirección, en este caso "MainAddress" es la propiedad de la vista que contiene un objeto AddressView ... –

+0

Eso es un buen trabajo gracias por salvarme un día ... – user1811801

Cuestiones relacionadas