¿Cómo persistir los modelos de datos pasados ​​a vistas parciales?

Para ilustrar el problema al que me enfrento, he reunido tres modelos de datos simples:

public class PersonalModel { public string FirstName { get; set; } public string LastName { get; set; } } public class AddressModel { public string Street { get; set; } } public class OverallModel { public string Id { get; set; } public PersonalModel Personal { get; set; } public AddressModel Address { get; set; } } 

Aquí está mi simple Index.chtml:

 @model WebAppTest.Models.OverallModel @using (Html.BeginForm()) { @Html.AntiForgeryToken() 

OverallModel


@Html.ValidationSummary(true, "", new { @class = "text-danger" }) @Html.HiddenFor(model => model.Id)
@Html.Partial("Personal", Model.Personal)
@Html.Partial("Address", Model.Address)
}

Cuando se hace clic en el botón “Guardar”, se invoca el siguiente método de control:

 [HttpPost] public ActionResult Index(OverallModel model) { return View(model); } 

El problema que tengo es ese model.Personal y model.Address valores de dirección siempre aparecen como nulos en el método del controlador.

Aunque los valores se pasan correctamente a las vistas parciales, el motor Razor no puede volver a juntar el objeto cuando se hace clic en Enviar.

Me gustaría que pudieras aclararme sobre qué es lo que me estoy perdiendo. Saludos.

Pase el OverallModel a sus parciales para que los controles se denominen correctamente y se vuelvan a publicar en OverallModel . En la actualidad, tendría controles con name="FirstName" pero deben ser name="Personal.FirstName"

 @Html.Partial("Personal", Model) 

y cambiar los parciales para adaptarse

 @model OverallModel .... @Html.TextBoxFor(m => m.Personal.FirstName) 

Como alternativa, también puede pasar el prefijo al parcial

 @Html.Partial("Address", Model.Personal, new ViewDataDictionary { TemplateInfo = new TemplateInfo { HtmlFieldPrefix = "Personal" }}) 

Tuve el mismo problema que tú, así que pondré mis 2 centavos aquí para alguien en el futuro con el mismo problema.

Mi solución es mediante el uso de EditorTemplates.

Usted crea sus modelos también conocidos como Personal, Address, Overal.

En el controlador (poner cualquier nombre), crea una instancia de modelo Overal y en el método Get lo envía a su vista y en el método Post lo coloca como parámetro entrante.

  public ActionResult Index() { var model = new OveralModel(); return View(model); } [HttpPost] public ActionResult Index(OveralModel model) { return View(model); } 

La página de índice (usaré la tuya) se verá así

 @model EditorFor.Models.OveralModel @using (Html.BeginForm()) { @Html.AntiForgeryToken() 

OverallModel


@Html.ValidationSummary(true, "", new { @class = "text-danger" }) @Html.HiddenFor(m => m.Id)
@Html.EditorFor(m => m.Personal)
@Html.EditorFor(m => m.Address)
}

En lugar de PartialViews podemos usar EditorModels, lo entiendo como un PartialView que podemos usar como editor cuando queramos.

Entonces, para usarlo, creamos una carpeta llamada EditorTemplates en las Vistas / Compartidas y creamos Vistas con los mismos nombres que sus modelos.

Por ejemplo, EditorTemplate para nuestro modelo personal se llamará PersonalModel.cshtml y el código puede parecerse a esto

 @model EditorFor.Models.PersonelModel 
@Html.LabelFor(model => model.FirstName, htmlAttributes: new { @class = "control-label col-md-2" })
@Html.EditorFor(model => model.FirstName, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.FirstName, "", new { @class = "text-danger" })
@Html.LabelFor(model => model.LastName, htmlAttributes: new { @class = "control-label col-md-2" })
@Html.EditorFor(model => model.LastName, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.LastName, "", new { @class = "text-danger" })

Entonces, cuando escribamos en nuestro sou @Html.EditorFor(m => m.Personal) , buscará en EditorTemplates y buscará un EditorTemplate con el mismo nombre y lo usará en el sitio.

El sitio del índice se verá así

y cuando haces clic en el botón Enviar enviará todo el modelo nuevamente al Controlador

Parece que funcionó y recuperamos nuestros datos y los usamos para lo que queramos.

PD: Mi primera publicación, así que espero que sea comprensible y que sea útil para otros incluso ahora y en el futuro. Tenga un buen día