vista tutorial net mvc modelo form controlador asp c# asp.net-mvc-3 viewmodel automapper

c# - tutorial - Usando modelos de vista en ASP.NET MVC 3



mvc c# tutorial (2)

Soy relativamente nuevo para ver modelos y tengo algunos problemas con su uso. Aquí hay una situación en la que me pregunto cuál es la mejor práctica ...

Estoy poniendo toda la información que una vista necesita en el modelo de vista. Aquí hay un ejemplo: perdonen cualquier error, esto está codificado desde lo alto de mi cabeza.

public ActionResult Edit(int id) { var project = ProjectService.GetProject(id); if (project == null) // Something about not found, possibly a redirect to 404. var model = new ProjectEdit(); model.MapFrom(project); // Extension method using AutoMapper. return View(model); }

Si la pantalla solo permite la edición de uno o dos campos, cuando el modelo de vista vuelve, faltan algunos datos (como debería ser).

[HttpPost] public ActionResult Edit(int id, ProjectEdit model) { var project = ProjectService.GetProject(id); if (project == null) // Something about not found, possibly a redirect to 404. try { if (!ModelState.IsValid) return View(model) // Won''t work, view model is incomplete. model.MapTo(project); // Extension method using AutoMapper. ProjectService.UpdateProject(project); // Add a message for the user to temp data. return RedirectToAction("details", new { project.Id }); } catch (Exception exception) { // Add a message for the user to temp data. return View(model) // Won''t work, view model is incomplete. } }

Mi solución temporal es recrear el modelo de vista desde cero, repoblarlo desde el modelo de dominio, volver a aplicar los datos del formulario y luego proceder de la forma habitual. Pero esto hace que el parámetro del modelo de vista sea un tanto inútil.

[HttpPost] public ActionResult Edit(int id, ProjectEdit model) { var project = ProjectService.GetProject(id); if (project == null) // Something about not found, possibly a redirect to 404. // Recreate the view model from scratch. model = new ProjectEdit(); model.MapFrom(project); // Extension method using AutoMapper. try { TryUpdateModel(model); // Reapply the form data. if (!ModelState.IsValid) return View(model) // View model is complete this time. model.MapTo(project); // Extension method using AutoMapper. ProjectService.UpdateProject(project); // Add a message for the user to temp data. return RedirectToAction("details", new { project.Id }); } catch (Exception exception) { // Add a message for the user to temp data. return View(model) // View model is complete this time. } }

¿Hay una forma más elegante?

EDITAR

Ambas respuestas son correctas, por lo que les daría las dos si pudiera. Sin embargo, el guiño va a MJ, ya que después de la prueba y el error, encuentro que su solución es la más inteligente.

Todavía puedo usar a los ayudantes, Jimmy. Si agrego lo que necesito que se muestre en la bolsa de visualización (o en la vista de datos), así ...

ViewBag.Project= project;

Entonces puedo hacer lo siguiente ...

@Html.LabelFor(model => ((Project)ViewData["Project"]).Name) @Html.DisplayFor(model => ((Project)ViewData["Project"]).Name)

Un poco de un hack, y requiere que el modelo de dominio esté decorado con System.ComponentModel.DisplayNameAttribute en algunos casos, pero ya lo hago.

Me encantaría llamar ...

@Html.LabelFor(model => ViewBag.Project.Name)

Pero la dinámica causa un problema en las expresiones.


Después de un aprendizaje de prueba y error (también conocido como código, luego odio), mi enfoque preferido actualmente es:

Uso los modelos de vista solo para enlazar campos de entrada. Entonces, en su caso, si su vista solo está editando dos campos, entonces su modelo de vista solo tendrá dos propiedades. Para los datos necesarios para rellenar la vista (listas desplegables, etiquetas, etc.), utilizo el ViewBag dinámico.

Creo que mostrar la vista (es decir, rellenar todo lo que la vista necesita mostrar) y capturar los valores de formulario publicados (enlace, validación, etc.) son dos preocupaciones separadas. Y me parece que mezclar los datos necesarios para rellenar la vista con lo que se publica desde la vista se vuelve desordenado y crea su situación exactamente más a menudo que no. No me gustan los objetos parcialmente poblados que se pasan alrededor.

Sin embargo, no estoy seguro de cómo funciona esto con Automapper (para asignar el objeto de dominio al ViewBag dinámico), ya que no lo he usado. Creo que tiene un método DynamicMap que puede funcionar? No debería tener problemas al asignar automáticamente el ViewModel de tipo fuerte al objeto de dominio.


Si entiendo correctamente, su modelo de vista probablemente se vea muy similar a su entidad de dominio. Usted mencionó que el modelo de visualización puede volver casi vacío porque solo algunos campos fueron editables.

Suponiendo que tiene una vista donde solo unos pocos campos están disponibles para edición (o visualización), estos son los únicos campos que debe tener disponibles en su modelo de vista. Por lo general, creo un modelo de vista por vista, y dejo que el controlador o un servicio maneje las entradas del usuario y las asigne de nuevo con la entidad de dominio después de realizar una validación.

Here un hilo sobre las mejores prácticas para los modelos de visualización que pueden resultarle útiles.

Editar: También puede aceptar un modelo de vista diferente en su acción Editar / POST de lo que sirve su acción Editar / GET. Creo que esto debería funcionar siempre que la carpeta del modelo pueda resolverlo.