vistas vista usar una pasar parciales parcial parametros pagina otra net mvc multiples misma datos controlador como cargar asp asp.net-mvc model partial-views

asp.net mvc - usar - obtener los valores de un objeto complejo anidado que se pasa a una vista parcial



pasar parametros de una vista a un controlador mvc (3)

Tengo un ViewModel que tiene un objeto complejo como uno de sus miembros. El objeto complejo tiene 4 propiedades (todas las cadenas). Estoy tratando de crear una vista parcial reutilizable donde pueda pasar el objeto complejo y hacer que genere el html con ayudantes html para sus propiedades. Todo eso funciona muy bien. Sin embargo, cuando envío el formulario, la carpeta del modelo no está asignando los valores al miembro de ViewModel, por lo que no obtengo nada del lado del servidor. ¿Cómo puedo leer los valores que un usuario escribe en los ayudantes html para el objeto complejo?

ViewModel

public class MyViewModel { public string SomeProperty { get; set; } public MyComplexModel ComplexModel { get; set; } }

MyComplexModel

public class MyComplexModel { public int id { get; set; } public string Name { get; set; } public string Address { get; set; } .... }

Controlador

public class MyController : Controller { public ActionResult Index() { MyViewModel model = new MyViewModel(); model.ComplexModel = new MyComplexModel(); model.ComplexModel.id = 15; return View(model); } [HttpPost] public ActionResult Index(MyViewModel model) { // model here never has my nested model populated in the partial view return View(model); } }

Ver

@using(Html.BeginForm("Index", "MyController", FormMethod.Post)) { .... @Html.Partial("MyPartialView", Model.ComplexModel) }

Vista parcial

@model my.path.to.namespace.MyComplexModel @Html.TextBoxFor(m => m.Name) ...

¿Cómo puedo vincular estos datos en el envío del formulario para que el modelo principal contenga los datos ingresados ​​en el formulario web desde la vista parcial?

Gracias

EDITAR: He descubierto que necesito anteponer "ComplexModel". a todos los nombres de mi control en la vista parcial (cuadros de texto) para que se asigne al objeto anidado, pero no puedo pasar el tipo ViewModel a la vista parcial para obtener esa capa adicional porque debe ser genérico para aceptar varios ViewModel tipos. Podría reescribir el atributo de nombre con javascript, pero eso me parece demasiado gueto. ¿De qué otra manera puedo hacer esto?

EDITAR 2: puedo establecer estáticamente el atributo de nombre con el nuevo {Name = "ComplexModel.Name"}, así que creo que estoy en el negocio a menos que alguien tenga un mejor método.


Me encontré con la misma situación y con la ayuda de tales publicaciones informativas cambié mi código parcial para tener un prefijo generado en los elementos de entrada generados por la vista parcial

He usado Html.partial helper dando nombre de vista parcial y objeto de ModelType y una instancia de objeto ViewDataDictionary con Html Field Prefix al constructor de Html.partial.

Esto da como resultado la solicitud GET de "xyz url" de "Vista principal" y muestra una vista parcial dentro de ella con elementos de entrada generados con el prefijo, por ejemplo, Nombre = "Título" ahora se convierte en Nombre = "MySubType.Title" en el elemento HTML respectivo y lo mismo para resto de los elementos de entrada del formulario.

El problema se produjo cuando la solicitud POST se realiza en "xyz url", esperando que el formulario que se completa se guarde en mi base de datos. Pero MVC Modelbinder no enlazó los datos de mi modelo POSTed con los valores de formulario rellenados y también ModelState también se perdió. El modelo en viewdata también se estaba volviendo nulo.

Finalmente, intenté actualizar los datos del modelo en forma Publicada usando el método TryUppdateModel que toma la instancia del modelo y el prefijo html que se pasó anteriormente a la vista parcial, y puedo ver que ahora el modelo está vinculado con valores y el estado del modelo también está presente.

¡Avíseme si este enfoque está bien o está un poco diversificado!


Puede intentar pasar el ViewModel al parcial.

@model my.path.to.namespace.MyViewModel @Html.TextBoxFor(m => m.ComplexModel.Name)

Editar

Puede crear un modelo base e insertar el modelo complejo allí y pasar el modelo basado al parcial.

public class MyViewModel :BaseModel { public string SomeProperty { get; set; } } public class MyViewModel2 :BaseModel { public string SomeProperty2 { get; set; } } public class BaseModel { public MyComplexModel ComplexModel { get; set; } } public class MyComplexModel { public int id { get; set; } public string Name { get; set; } ... }

Entonces su parcial será como a continuación:

@model my.path.to.namespace.BaseModel @Html.TextBoxFor(m => m.ComplexModel.Name)

Si esta no es una solución aceptable, es posible que tenga que pensar en términos de anular la carpeta del modelo. Puedes leer sobre eso here .


Puede pasar el prefijo al parcial usando

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

que le asignará el prefijo controles de atributo de name para que <input name="Name" ../> se convierta en <input name="ComplexModel.Name" ../> y se vincule correctamente al tipo de MyViewModel en la publicación posterior

Editar

Para hacerlo un poco más fácil, puede encapsular esto en un ayudante html

public static MvcHtmlString PartialFor<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression, string partialViewName) { string name = ExpressionHelper.GetExpressionText(expression); object model = ModelMetadata.FromLambdaExpression(expression, helper.ViewData).Model; var viewData = new ViewDataDictionary(helper.ViewData) { TemplateInfo = new System.Web.Mvc.TemplateInfo { HtmlFieldPrefix = string.IsNullOrEmpty(helper.ViewData.TemplateInfo.HtmlFieldPrefix) ? name : $"{helper.ViewData.TemplateInfo.HtmlFieldPrefix}.{name}" } }; return helper.Partial(partialViewName, model, viewData); }

y úsalo como

@Html.PartialFor(m => m.ComplexModel, "MyPartialView")