This article has been localized into Spanish by the community.
Pasando datos a la Vistas
Un View puede existir sin un Model o cualquier otro dato del backend, pero en la mayoría de los casos, necesitas de alguna forma acceder a los datos disponibles por el Controller en tu vista. Dado que tu vista no debe saber sobre tu Controller (como lo dicta la regla de separación de intereses), tu Controller es responsable de hacer los datos disponibles para el View. Hay dos formas principales de lograr esto: definir un Modelo específico fuertemente tipado y luego pasárselo a la Vista, o usar los contenedores ViewData/ViewBag para volver disponibles los datos a la Vista. Discutiremos estas formas ahora.
Por favor, nota que habrá un poco de información solapada en este artículo y el artículo de inicio rápido para agregar un Model al proyecto.
Usando un (View) Model
Ya que la tecnología se llama MVC, nombre corto para Modelo-Vista-Controlador o Model-View-Controller, el uso de un (View) Model es definitivamente la forma más limpia y más común de pasar datos al View. Hablaremos más del Model después en este tutorial, pero por ahora, sabes que básicamente es un objeto que representa algo del mundo real. También verás el concepto de un "View Model" - de nuevo, entraremos en mayor profundidad en el tema más adelante -, pero descrito brevemente, un View Model es solo un Modelo pasado a la Vista. Puede ser algo que ya exista en tu proyecto, como un objeto User o un Product, o una clase que definas para representar los datos que deseas acceder desde tu vista.
Un Model no tiene que ser una clase compleja, puede ser, en teoría, algo tan simple como un String, un entero o un DateTime. En otras palabras, cualquier cosa en el framework .NET que pueda ser usado como un Model, pero en la practica, tu Modelo usualmente será una clase que consiste en al menos un par de propiedades. Por ejemplo, un Modelo usado para representar un Producto podría verse así:
public class Product
{
public string Title { get; set; }
public double Price { get; set; }
}
La conexión entre el Model y el View es hecha por el Controller - este puede tomar datos de entrada del usuario y convertirla en datos relevantes para la vista, por ejemplo:
public IActionResult Details(int id)
{
Product product = new Product()
{
Title = "Toilet Paper",
Price = 1.99
};
return View(product);
}
Nota como paso la instancia product al View cuando llamo al método View(). Dentro el View Product/Details, puedo definir la clase Product como el Model que este View puede (y debe) esperar, usando la directiva @model, localizada al inicio del archivo de Vista:
@model HelloMVCWorld.Models.Product
Con eso en su lugar, ahora puedes empezar a usar tu (View) Model y sus propiedades en tu vista:
@model HelloMVCWorld.Models.Product
<h1>@Model.Title</h1>
Price: @Model.Price
Gracias al hecho de que especificas un tipo como Model de tu Vista, tendrás ayuda para accesar a los miembros del objeto a través de IntelliSense y tu código será validado durante el proceso de Construcción (Build), para asegurarse que solo uses propiedades o métodos encontrados en el objeto Model.
Vistas dinámicas
Sí tu no declaras un tipo de Modelo para tu Vista, usando la directiva @model, la vista no esperará ningun Modelo de algún tipo en especifico para serle pasado, pero eso no te priva de hacer esto o incluso usar el objeto. Esto es referido frecuentemente como una Vista dinámica o Dynamic View, y no es muy frecuente su uso, porque pierdes el beneficio del soporte de IntelliSense y la revisión en tiempo de compilación de las propiedades.
Entonces, puedes tomar el ejemplo de arriba y remover la directiva @model en el inicio del View, y aun funcionará. En esta situación, la propiedad Model será considerada como un objeto dinámico, donde puedes accesar a las propiedades sin la revisión de compilación de su existencia. Desde luego que también significa que sí tratas de acceder a propiedades que no existen, la generación de la página fallará durante el tiempo de ejecución, resultando en una fea excepción. Por lo tanto, las vistas dinámicas no son usadas mucho.
Usando los contenedores ViewData/ViewBag
Como una alternativa al enfoque de tipado riguroso para pasar datos a la vista, puedes usar el contenedor llamado ViewData/ViewBag. Puedes agregar cosas a ellos desde el Controller y luego automáticamente poder accesar a los datos almacenados en tus Vistas. De hecho es bastante simple y puedes lograr casi las mismas cosas que sí usaras el Modelo con tipado riguroso. Aquí hay un ejemplo:
public IActionResult DetailsViewData(int id)
{
ViewBag.ProductTitle = "Toilet Paper";
ViewBag.ProductPrice = 1.99;
return View();
}
Ahora puedes acceder a los datos en tu View así de simple, gracias a la siempre disponible propiedad llamada ViewBag:
<h1>@ViewBag.ProducTtitle</h1>
Price: @ViewBag.ProductPrice
La mayor diferencia aquí es que no hay revisión en tiempo de compilación para estas propiedades, tampoco hay ayuda de IntelliSense cuando las escribes. En otras palabras, puedes escribir mal el nombre de una propiedad y no te darás cuenta hasta que intentes usar la vista. Por lo tanto deberías usar el ViewData/ViewBag una cantidad baja de veces. Sin embargo, debes recordar que eres libre de combiar el uso del ViewData/ViewBag con una tradicional vista de tipado riguroso.
¿Qué es la diferencia entre ViewData y ViewBag?
Notarás que he usado dos términos para tratar con datos de vista dinámica: Las propiedades ViewData y ViewBag. Estas se refieren a la misma cosa, el cual es un diccionario de llaves y valores (los objetos). Sin embargo, el ViewBag es una representación DynamicObject del Dictionario, permitiéndote acceder a los datos como sí fueran propiedades del objeto ViewBag, en vez de entradas en un diccionario. Eres libre de usar ambas propiedades intercambiándolas, ya que ambas se refieren a los mismo datos, así que por comprobación, aquí hay un ejemplo de como se vería sí usas ambos enfoques:
Controller(controller):
public IActionResult DetailsViewData(int id)
{
ViewData["ProductTitle"] = "Toilet Paper";
ViewBag.ProductPrice = 1.99;
return View();
}
View (Vista):
<h1>@ViewData["ProducTtitle"]</h1>
Price: @ViewBag.ProductPrice
Nota como uso el ViewData y por lo tanto un enfoque basado en diccionario para leer y escribir el ProductTitle, mientras uso una notación de objeto basada en punto para acceder al ProductTitle. Eso te deja con una diferencia mas pequeña, por ejemplo, la habilidad de revisar la presencia de una dada llave/valor en la collecion ViewData (usando el método ContainsKey()). Al final del día, debes usar el enfoque que más te agrade y luego mantenerte con ese por consistencia.
Resumen
Puedes pasar datos de un Controller a la Vista usando diferentes enfoques, pero el recomendado es casi siempre la vista con tipado riguroso, donde defines el tipo de Model que tu vista espera. Esto te da soporte de IntelliSense y la revisión en tiempo de compilación de las propiedades y métodos que intentas usar.