Soy nuevo en ASP.NET MVC. Tengo un problema para comprender el propósito de un ViewModel.
¿Qué es un ViewModel y por qué necesitamos un ViewModel para una aplicación ASP.NET MVC?
Si obtengo un buen ejemplo sobre su funcionamiento y explicación, sería mejor.
asp.net-mvc
viewmodel
único
fuente
fuente
Respuestas:
A
view model
representa los datos que desea mostrar en su vista / página, ya sea que se use para texto estático o para valores de entrada (como cuadros de texto y listas desplegables) que se pueden agregar a la base de datos (o editar). Es algo diferente a tudomain model
. Es un modelo para la vista.Digamos que tiene una
Employee
clase que representa el modelo de dominio de su empleado y que contiene las siguientes propiedades (identificador único, nombre, apellido y fecha de creación):Los modelos de vista difieren de los modelos de dominio en que los modelos de vista solo contienen los datos (representados por las propiedades) que desea usar en su vista. Por ejemplo, supongamos que desea agregar un nuevo registro de empleado, su modelo de vista podría verse así:
Como puede ver, solo contiene dos de las propiedades. Estas dos propiedades también están en el modelo de dominio del empleado. ¿Por qué es esto lo que puedes preguntar?
Id
podría no establecerse desde la vista, podría generarse automáticamente por la tabla Empleado. YDateCreated
también se puede configurar en el procedimiento almacenado o en la capa de servicio de su aplicación. Por lo tantoId
, yDateCreated
no son necesarios en el modelo de vista. Es posible que desee mostrar estas dos propiedades cuando vea los detalles de un empleado (un empleado que ya ha sido capturado) como texto estático.Al cargar la vista / página, el método de acción de creación en el controlador de su empleado creará una instancia de este modelo de vista, completará los campos si es necesario y luego pasará este modelo de vista a la vista / página:
Su vista / página podría verse así (suponiendo que esté utilizando
ASP.NET MVC
y elRazor
motor de visualización):Por lo tanto, la validación se haría solo en
FirstName
yLastName
. Usando FluentValidation puede tener una validación como esta:Y con las anotaciones de datos podría verse así:
La clave para recordar es que el modelo de vista solo representa los datos que desea usar , nada más. Puede imaginar todo el código y la validación innecesarios si tiene un modelo de dominio con 30 propiedades y solo desea actualizar un solo valor. Dado este escenario, solo tendría este valor / propiedad en el modelo de vista y no todas las propiedades que están en el objeto de dominio.
Un modelo de vista no solo puede tener datos de una tabla de base de datos. Puede combinar datos de otra tabla. Tome mi ejemplo anterior sobre agregar un nuevo registro de empleado. Además de agregar solo el nombre y el apellido, es posible que también desee agregar el departamento del empleado. Esta lista de departamentos vendrá de su
Departments
mesa. Entonces ahora tiene datos de las tablasEmployees
yDepartments
en un modelo de vista. Solo tendrá que agregar las siguientes dos propiedades a su modelo de vista y llenarlo con datos:Al editar datos de empleados (un empleado que ya se ha agregado a la base de datos), no diferiría mucho de mi ejemplo anterior. Cree un modelo de vista, llámelo por ejemplo
EditEmployeeViewModel
. Solo tenga los datos que desea editar en este modelo de vista, como nombre y apellido. Edite los datos y haga clic en el botón Enviar. No me preocuparía demasiado por elId
campo porque elId
valor probablemente estará en la URL, por ejemplo:Tome esto
Id
y páselo a su capa de repositorio, junto con sus valores de nombre y apellido.Al eliminar un registro, normalmente sigo la misma ruta que con el modelo de vista de edición. También tendría una URL, por ejemplo:
Cuando la vista se carga por primera vez, obtenía los datos del empleado de la base de datos usando el
Id
3. Entonces, simplemente mostraba texto estático en mi vista / página para que el usuario pueda ver qué empleado se está eliminando. Cuando el usuario hace clic en el botón Eliminar, simplemente usaría elId
valor de 3 y lo pasaría a mi capa de repositorio. Solo necesitaId
eliminar un registro de la tabla.Otro punto, realmente no necesita un modelo de vista para cada acción. Si se trata de datos simples, estaría bien usarlos solo
EmployeeViewModel
. Si se trata de vistas / páginas complejas y difieren entre sí, le sugiero que utilice modelos de vista separados para cada una.Espero que esto aclare cualquier confusión que haya tenido sobre los modelos de vista y los modelos de dominio.
fuente
El modelo de vista es una clase que representa el modelo de datos utilizado en una vista específica. Podríamos usar esta clase como modelo para una página de inicio de sesión:
Con este modelo de vista puede definir la vista (motor de vista Razor):
Y acciones:
Lo que produce este resultado (la pantalla se toma después de enviar el formulario, con mensajes de validación):
Como puede ver, un modelo de vista tiene muchos roles:
LabelFor
,EditorFor
,DisplayFor
ayudantes).Otro ejemplo de un modelo de vista y su recuperación: queremos mostrar los datos básicos del usuario, sus privilegios y el nombre del usuario. Creamos un modelo de vista especial, que contiene solo los campos obligatorios. Recuperamos datos de diferentes entidades de la base de datos, pero la vista solo conoce la clase de modelo de vista:
Recuperación:
fuente
Editar: Actualicé esta respuesta en mi Blog:
http://www.samwheat.com/post/The-function-of-ViewModels-in-MVC-web-development
Mi respuesta es un poco larga, pero creo que es importante comparar los modelos de vista con otros tipos de modelos de uso común para comprender por qué son diferentes y por qué son necesarios.
Para resumir y responder directamente a la pregunta que se hace:
En términos generales, un modelo de vista es un objeto que contiene todas las propiedades y métodos necesarios para representar una vista. Las propiedades del modelo de vista a menudo están relacionadas con objetos de datos, como clientes y pedidos, y además contienen propiedades relacionadas con la página o la aplicación en sí, como el nombre de usuario, el nombre de la aplicación, etc. Los modelos de vista proporcionan un objeto conveniente para pasar a un motor de renderizado. crear una página html Una de las muchas razones para usar un modelo de vista es que los modelos de vista proporcionan una forma de probar unitariamente ciertas tareas de presentación, como manejar la entrada del usuario, validar datos, recuperar datos para mostrar, etc.
Aquí hay una comparación de los modelos de entidad (también conocidos como modelos DTO), modelos de presentación y modelos de vista.
Objetos de transferencia de datos, también conocido como "Modelo"
Un objeto de transferencia de datos (DTO) es una clase con propiedades que coinciden con un esquema de tabla en una base de datos. Los DTO se nombran por su uso común para transferir datos hacia y desde un almacén de datos.
Características de los DTO:
• Son objetos comerciales: su definición depende de los datos de la aplicación.
• Por lo general, solo contienen propiedades, sin código.
• Se utiliza principalmente para transportar datos hacia y desde una base de datos.
• Las propiedades coinciden exacta o estrechamente con los campos de una tabla específica en un almacén de datos.
Las tablas de la base de datos generalmente se normalizan, por lo tanto, los DTO también se normalizan. Esto los hace de uso limitado para presentar datos. Sin embargo, para ciertas estructuras de datos simples, a menudo funcionan bastante bien.
Aquí hay dos ejemplos de cómo se verían los DTO:
Modelos de presentación
Un modelo de presentación es una utilidad. clase de que se utiliza para representar datos en una pantalla o informe. Los modelos de presentación generalmente se usan para modelar estructuras de datos complejas que se componen de datos de múltiples DTO. Los modelos de presentación a menudo representan una vista desnormalizada de datos.
Características de los modelos de presentación:
• Son objetos comerciales: su definición depende de los datos de la aplicación.
• Contienen principalmente propiedades. El código generalmente se limita a formatear datos o convertir ao desde un DTO. Los modelos de presentación no deben contener lógica empresarial.
• A menudo presentan una vista desnormalizada de datos. Es decir, a menudo combinan propiedades de múltiples DTO.
• A menudo contienen propiedades de un tipo base diferente que un DTO. Por ejemplo, los montos en dólares pueden representarse como cadenas para que puedan contener comas y un símbolo de moneda.
• A menudo se define por cómo se usan, así como por sus características de objeto. En otras palabras, un DTO simple que se utiliza como modelo de respaldo para representar una cuadrícula es, de hecho, también un modelo de presentación en el contexto de esa cuadrícula.
Los modelos de presentación se usan "según sea necesario" y "donde sea necesario" (mientras que los DTO generalmente están vinculados al esquema de la base de datos). Se puede usar un modelo de presentación para modelar datos para una página completa, una cuadrícula en una página o un menú desplegable en una cuadrícula en una página. Los modelos de presentación a menudo contienen propiedades que son otros modelos de presentación. Los modelos de presentación a menudo se construyen para un propósito de un solo uso, como representar una cuadrícula específica en una sola página.
Un ejemplo de modelo de presentación:
Ver modelos
Un modelo de vista es similar a un modelo de presentación, ya que es una clase de respaldo para representar una vista. Sin embargo, es muy diferente de un Modelo de Presentación o un DTO en cuanto a cómo se construye. Los modelos de vista a menudo contienen las mismas propiedades que los modelos de presentación y los DTO y, por esta razón, a menudo se confunden uno con el otro.
Características de los modelos de vista:
• Son la única fuente de datos utilizada para representar una página o pantalla. Por lo general, esto significa que un modelo de vista expondrá cada propiedad que cualquier control en la página necesitará para representarse correctamente. Hacer que el modelo de vista sea la única fuente de datos para la vista mejora en gran medida su capacidad y valor para las pruebas unitarias.
• Son objetos compuestos que contienen propiedades que consisten en datos de la aplicación, así como propiedades que utiliza el código de la aplicación. Esta característica es crucial al diseñar el modelo de vista para su reutilización y se discute en los ejemplos a continuación.
• Contiene el código de la aplicación. Los modelos de vista generalmente contienen métodos que se invocan durante la representación y cuando el usuario interactúa con la página. Este código generalmente se relaciona con el manejo de eventos, la animación, la visibilidad de los controles, el estilo, etc.
• Contener código que llame a servicios comerciales con el propósito de recuperar datos o enviarlos a un servidor de base de datos. Este código a menudo se coloca por error en un controlador. Llamar a los servicios comerciales desde un controlador generalmente limita la utilidad del modelo de vista para pruebas unitarias. Para ser claros, los modelos de vista en sí mismos no deben contener lógica empresarial, sino que deben realizar llamadas a servicios que sí contienen lógica empresarial.
• A menudo contienen propiedades que son otros modelos de vista para otras páginas o pantallas.
• Están escritos "por página" o "por pantalla". Por lo general, se escribe un modelo de vista único para cada página o pantalla de una aplicación.
• Generalmente derivan de una clase base ya que la mayoría de las páginas y pantallas comparten propiedades comunes.
Ver composición del modelo
Como se indicó anteriormente, los modelos de vista son objetos compuestos en el sentido de que combinan propiedades de aplicación y propiedades de datos comerciales en un solo objeto. Los ejemplos de propiedades de aplicación de uso común que se usan en los modelos de vista son:
• Propiedades que se utilizan para mostrar el estado de la aplicación, como mensajes de error, nombre de usuario, estado, etc.
• Propiedades utilizadas para formatear, mostrar, estilizar o animar controles.
• Propiedades utilizadas para el enlace de datos, como objetos de lista y propiedades que contienen datos intermedios que ingresa el usuario.
Los siguientes ejemplos muestran por qué la naturaleza compuesta de los modelos de vista es importante y cómo podemos construir mejor un Modelo de vista que sea eficiente y reutilizable.
Supongamos que estamos escribiendo una aplicación web. Uno de los requisitos del diseño de la aplicación es que el título de la página, el nombre de usuario y el nombre de la aplicación se deben mostrar en cada página. Si queremos crear una página para mostrar un objeto de orden de presentación, podemos modificar el modelo de presentación de la siguiente manera:
Este diseño podría funcionar ... pero ¿qué pasa si queremos crear una página que muestre una lista de pedidos? Las propiedades PageTitle, UserName y ApplicationName se repetirán y serán difíciles de manejar. Además, ¿qué pasa si queremos definir alguna lógica a nivel de página en el constructor de la clase? Ya no podemos hacer eso si creamos una instancia para cada pedido que se mostrará.
Composición sobre herencia
Aquí hay una manera en que podríamos re-factorizar el modelo de presentación de orden de modo que se convierta en un modelo de vista real y sea útil para mostrar un solo objeto PresentationOrder o una colección de objetos PresentationOrder:
Mirando las dos clases anteriores, podemos ver que una forma de pensar sobre un modelo de vista es que es un modelo de presentación que contiene otro modelo de presentación como una propiedad. El modelo de presentación de nivel superior (es decir, el modelo de vista) contiene propiedades que son relevantes para la página o la aplicación, mientras que el modelo de presentación (propiedad) contiene propiedades que son relevantes para los datos de la aplicación.
Podemos llevar nuestro diseño un paso más allá y crear una clase de modelo de vista base que se pueda usar no solo para PresentationOrders, sino también para cualquier otra clase:
Ahora podemos simplificar nuestro PresentationOrderVM así:
Podemos hacer que nuestro BaseViewModel sea aún más reutilizable haciéndolo genérico:
Ahora nuestras implementaciones son fáciles:
fuente
MyViewModel<MyPresModel>
Si tiene propiedades específicas de la vista y no están relacionadas con el almacén de DB / Servicio / Datos, es una buena práctica usar ViewModels. Digamos que desea dejar una casilla de verificación seleccionada en función de un campo DB (o dos) pero el campo DB en sí no es un booleano. Si bien es posible crear estas propiedades en el Modelo mismo y mantenerlo oculto del enlace a los datos, es posible que no desee saturar el Modelo dependiendo de la cantidad de dichos campos y transacciones.
Si hay muy pocos datos y / o transformaciones específicos de la vista, puede usar el Modelo mismo
fuente
No leí todas las publicaciones, pero en cada respuesta me falta un concepto que realmente me ayudó a "entenderlo" ...
Si un modelo es similar a una tabla de base de datos , entonces un modelo de vista es similar a una vista de base de datos : una vista generalmente devuelve pequeñas cantidades de datos de una tabla o conjuntos complejos de datos de varias tablas (combinaciones).
Me encuentro usando ViewModels para pasar información a una vista / formulario, y luego transfiero esos datos a un Modelo válido cuando el formulario se publica nuevamente en el controlador, lo que también es muy útil para almacenar Listas (IEnumerable).
fuente
MVC no tiene un modelo de vista: tiene un modelo, vista y controlador. Un modelo de vista es parte de MVVM (Model-View-Viewmodel). MVVM se deriva del modelo de presentación y se populariza en WPF. También debería haber un modelo en MVVM, pero la mayoría de las personas pierden completamente el punto de ese patrón y solo tendrán una vista y un modelo de vista. El modelo en MVC es similar al modelo en MVVM.
En MVC el proceso se divide en 3 responsabilidades diferentes:
MVC no es muy adecuado para aplicaciones web. Es un patrón introducido por Smalltalk para crear aplicaciones de escritorio. Un entorno web se comporta completamente diferente. No tiene mucho sentido copiar un concepto de 40 años del desarrollo de escritorio y pegarlo en un entorno web. Sin embargo, mucha gente piensa que esto está bien, porque su aplicación compila y devuelve los valores correctos. En mi opinión, eso no es suficiente para declarar que una determinada elección de diseño está bien.
Un ejemplo de un modelo en una aplicación web podría ser:
El controlador puede usarlo así:
Sus métodos de controlador y sus modelos serán pequeños, fácilmente comprobables y al grano.
fuente
Ver modelo a es una clase simple que puede contener más de una propiedad de clase. Lo usamos para heredar todas las propiedades requeridas, por ejemplo, tengo dos clases Estudiante y Asunto
Ahora queremos mostrar los registros Nombre del alumno y Nombre del sujeto en la vista (en MVC), pero no es posible agregar más de una clase como:
el código anterior arrojará un error ...
Ahora creamos una clase y podemos darle cualquier nombre, pero este formato "XyzViewModel" hará que sea más fácil de entender. Es el concepto de herencia. Ahora creamos una tercera clase con el siguiente nombre:
Ahora usamos este ViewModel en View
Ahora podemos acceder a todas las propiedades de StudentViewModel y la clase heredada en View.
fuente
Muchos ejemplos importantes, déjenme explicarles de una manera clara y crujiente.
ViewModel = Modelo creado para servir la vista.
La vista ASP.NET MVC no puede tener más de un modelo, por lo que si necesitamos mostrar propiedades de más de un modelo en la vista, no es posible. ViewModel sirve para este propósito.
Ver modelo es una clase de modelo que puede contener solo aquellas propiedades que se requieren para una vista. También puede contener propiedades de más de una entidad (tablas) de la base de datos. Como su nombre indica, este modelo se crea específicamente para los requisitos de Vista.
Pocos ejemplos de modelos de vista están a continuación
ViewModel también se puede usar para insertar, actualizar registros en más de una entidad, sin embargo, el uso principal de ViewModel es mostrar columnas de múltiples entidades (modelo) en una sola vista.
La forma de crear ViewModel es la misma que crear Modelo, la forma de crear vista para Viewmodel es igual que crear vista para Modelo.
Aquí hay un pequeño ejemplo de datos de Lista usando ViewModel .
Espero que esto sea útil.
fuente
ViewModel es una solución alternativa que parchea la torpeza conceptual del marco MVC. Representa la cuarta capa en la arquitectura Modelo-Vista-Controlador de 3 capas. cuando el Modelo (modelo de dominio) no es apropiado, demasiado grande (más de 2-3 campos) para la Vista, creamos un Modelo de vista más pequeño para pasarlo a la Vista.
fuente
Un modelo de vista es un modelo conceptual de datos. Su uso es, por ejemplo, obtener un subconjunto o combinar datos de diferentes tablas.
Es posible que solo desee propiedades específicas, por lo que esto le permite cargar solo esas y no propiedades innecesarias adicionales
fuente
Diseñando ViewModel
Presentación del modelo de vista en la vista
Trabajando con acción
fuente
View Model es una clase que podemos usar para representar datos en View. Supongamos que tiene dos entidades Place y PlaceCategory y desea acceder a los datos de ambas entidades usando un solo modelo, luego usamos ViewModel.
Entonces, en el Ejemplo anterior, Lugar y Categoría son las dos entidades diferentes y el modelo de vista PlaceCategory es ViewModel que podemos usar en View.
fuente
Si desea estudiar el código de cómo configurar una aplicación web "Baseline" con ViewModels, puedo aconsejarle que descargue este código en GitHub: https://github.com/ajsaulsberry/BlipAjax . Desarrollé aplicaciones para grandes empresas. Cuando hace esto, es problemático configurar una buena arquitectura que maneje toda esta funcionalidad "ViewModel". Creo que con BlipAjax tendrás una muy buena "línea de base" para comenzar. Es solo un sitio web simple, pero excelente en su simplicidad. Me gusta la forma en que usaron el idioma inglés para señalar lo que realmente se necesita en la aplicación.
fuente