2012-06-29 30 views
27

Para la ViewBag, escuché que era un no-no para usar. Supongo que el contenido del ViewBag se debe incorporar a un modelo de vista?MVC ViewBag Best Practice

Pregunta:

  1. ¿Es mi suposición anterior la mejor práctica. (No usar ViewBag y segundo para tenerlo en el modelo de vista)

  2. ¿Hay situaciones en las que ViewBag es absolutamente necesario?

+7

Desde la perspectiva de Microsoft, no estamos de acuerdo con nunca usar ViewBag o ViewBag es un No No. Usar ViewBag para pasar los datos del modelo es otro asunto y debe desaconsejarse. Usar ViewBag para pasar metadatos (Seleccionar lista) está bien. Pro MVC de Sanderson y otros libros los usan y no hacen tales proclamaciones definitivas - 2. Abs necesario - Lo dudo. – RickAndMSFT

Respuesta

25

ViewBag es un diccionario dinámico. Por lo tanto, al usar ViewBag para transferir datos entre los métodos de acción y las vistas, su compilador no podrá detectar si usted hace un error en su código al intentar acceder al ítem ViewBag en su vista. Su vista se bloqueará en el tiempo de ejecución :(

En general, es una buena idea utilizar un modelo de vista para transferir datos entre sus métodos de acción y vistas. View model es una clase POCO simple que tiene propiedades específicas para la vista. si desea pasar algunos datos adicionales para ver, agregue una nueva propiedad a su modelo de vista y úselo. Las vistas muy tipeadas hacen que el código sea más limpio y más fácil de mantener. Con este enfoque, no es necesario que haga un casting explícito de su diccionario viewbag elemento para algunos tipos de ida y vuelta que usted tiene que ver con ver la bolsa.

public class ProductsForCategoryVm 
{ 
    public string CategoryName { set;get; } 
    public List<ProductVm> Products { set;get;}  
} 
public class ProductVm 
{ 
    public int Id {set;get;} 
    public string Name { set;get;} 
} 

y en su método de acción, cree un objeto de este modelo de vista, cargue las propiedades y enviar eso a la vista.

public ActionResult Category(int id) 
{ 
    var vm= new ProductsForCategoryVm(); 
    vm.CategoryName = "Books"; 
    vm.Products= new List<ProductVm> { 
    new ProductVm { Id=1, Name="The Pragmatic Programmer" }, 
    new ProductVm { Id=2, Name="Clean Code" } 
    } 
    return View(vm); 
} 

Y su punto de vista, que es fuertemente tipado al modelo de vista, los datos

@model ProductsForCategoryVm 
<h2>@Model.CategoryName</h2> 
@foreach(var item in Model.Products) 
{ 
    <p>@item.Name</p> 
} 

desplegables?

Una gran cantidad de tutoriales/libros tiene muestras de código que utiliza ViewBag para datos desplegables. Personalmente todavía siento que ViewBag no debería usarse para esto. Debe ser una propiedad del tipo List<SelectListItem> en su modelo de vista para pasar los datos desplegables. Aquí hay un post con un código de ejemplo sobre cómo hacerlo.

¿Hay situaciones en las que un ViewBag es absolutamente necesario?

Hay algunos casos de uso válidos donde se puede (no es necesario ) utiliza ViewBag para enviar datos. Por ejemplo, si desea mostrar algo en su página Diseño, puede usar ViewBag para eso. Otro ejemplo es ViewBag.Title(para el título de la página) presente en la plantilla MVC predeterminada.

public ActionResult Create() 
{ 
    ViewBag.AnnouncementForEditors="Be careful"; 
    return View(); 
} 

Y en el diseño, se puede leer la ViewBag.AnnouncementForEditors

<body> 
<h1>@ViewBag.AnnouncementForEditors</h1> 
<div class="container body-content"> 
    @RenderBody() 
</div> 
</body> 
+0

El modelo se almacena en ViewBag, por lo que siempre es necesario tenerlo. El uso de una cadena mágica puede no ser el punto máximo de la capacidad de mantenimiento, pero aparte de eso, utilizar un modelo es hacer cumplir la convención de declarar un tipo y una variable de página. –

0
  1. No. El uso ViewModels.
  2. No. Si diseña un modelo de vista perfecto, nunca necesitará un ViewBag.
4

1) Es mi suposición superior a la mejor práctica. (No usar un ViewBag y segundo para tenerlo en el modelo de vista)

Sí.

2) ¿Hay situaciones en las que un ViewBag es absolutamente necesario?

No. Todo lo que haya almacenado en una ViewBag podría ir al modelo de vista que se pasó a la vista.

+0

¿Qué pasa con los metadatos? ¿Deberíamos eliminar @ ViewBag.Title de las plantillas? – RickAndMSFT

+7

Yeap, arrójalo. Por favor. No quiero ver en ASP.NET MVC 4. Me da ganas de vomitar. Úselo internamente en el marco si lo marca como 'interno 'para que el desarrollador nunca tenga que enfrentarse a él. –

4

El problema con ViewBags y la mejor práctica recomendada se reduce a compilar control de tiempo. ViewBags son solo diccionarios y con eso obtiene cadenas mágicas, por lo que si termina cambiando el tipo de objeto de uno de los elementos del viewbag o el nombre de la clave no lo sabrá hasta el tiempo de ejecución, incluso si precompila las vistas usando <MvcBuildViews>true</MvcBuildViews>.

Es mejor observar los modelos, incluso si tiene que modificarlos para adaptarlos a una vista específica de vez en cuando.

26

1) Es mi suposición superior a la mejor práctica. (No usar un ViewBag y segundo para tenerlo en el modelo de vista)

que puedes usar ViewModels en lugar de los datos que pasan a través de ViewBag tanto como sea posible.

2) ¿Hay situaciones en las que un ViewBag es absolutamente necesario?

No hay ninguna situación en la que un ViewBag sea absolutamente necesario. Sin embargo, hay algunos datos que personalmente prefiero usar ViewBag en lugar de View Model. Por ejemplo, cuando necesito llenar un cuadro desplegable para valores predefinidos (es decir, Ciudades), uso ViewBag para llevar a la vista la matriz SelectListItem. Prefiero no contaminar mis ViewModels con estos datos.

+4

Excelente respuesta en alineación con nuestra guía publicada (MS). Solo lo cambiaría de pasar datos a pasar datos del modelo (sin metadatos) Ver la parte inferior de mi tutorial http://www.asp.net/mvc/tutorials/javascript/working-with-the-dropdownlist-box-and -jquery/examining-how-aspnet-mvc-scaffolds-the-dropdownlist-helper – RickAndMSFT

+0

@RickAndMSFT, debo administrar Aproveché su publicación cuando descubrí ViewBags por primera vez. Gran publicación por cierto. – SadullahCeran

+1

Buena respuesta, también creo que usar ViewBag contaminando un viewmodel con una lista de opciones para pasar a la vista es una buena práctica. Si se pasa una lista en el ViewModel es porque es probable que la lista se edite o porque "tiene sentido" para el modelo. Pero en el caso de una lista de opciones donde solo se seleccionará una, ViewBag parece más limpio. – iberodev

2

He encontrado algo de uso para ViewBag donde hay funcionalidad común en todas las páginas, y la funcionalidad no depende de la página que se muestra. Por ejemplo, supongamos que está creando StackOverflow. El tablero de trabajo aparece en cada página, pero los trabajos que se muestran no tienen nada que ver con la página (mi uso fue similar en concepto). Agregar una propiedad a cada ViewModel sería difícil y lento, y un lote de pelusa para sus pruebas. No creo que valga la pena en esta situación.

He utilizado una clase base ViewModel con los datos de corte transversal, pero si tiene más de uno (por ejemplo, trabajos & lista de sitios de intercambio de pila), debe comenzar a rellenar datos adicionales, o algún otro abuso de un ViewModel, además de que necesita un constructor ViewModel para rellenar los datos base.

En cuanto al problema de las cuerdas mágicas, hay muchas soluciones. Constantes, métodos de extensión, etc.

Con todo lo dicho, si tiene algo que se muestra en su página que depende del contexto de la página, un ViewModel es su amigo.

Erick

+0

Sé que esto es viejo, pero ¿no sería mejor utilizar un parcial para la lista de trabajos y @ {Html.RenderAction ("SomeAction", "SomeController");} desde la vista? – wingyip

1

modelo de vista Si no puede re-diseño existentes utilizan ViewBag.

0

2.¿Hay situaciones en las que un ViewBag es absolutamente necesario?

En algún caso, deberá compartir sus datos desde el Controlador a través de los diseños, vistas y vistas parciales. En este caso, ViewBag es muy útil y dudo que haya una mejor manera.

0

Si no hubiera casos de uso para ello, no se implementaría en primer lugar. Sí, puedes hacer todo con ViewModels, pero ¿qué pasa si realmente no necesitas uno? Uno de esos escenarios es editar entidades. Puede pasar DTO directamente como modelo.

@model CategoryDto 
<div class="md-form form-sm"> 
    <input asp-for="Name" class="form-control"> 
    <label asp-for="Name">("Category Name")</label> 
</div> 

¿Pero y si quieres seleccionar la categoría principal? DTO entidad mantiene idealmente solamente que los propios valores, por lo que para poblar la lista de selección utiliza ViewBag

<select asp-for="ParentId" asp-items="ViewBag.ParentList"> 
    <option value="">None</option> 
</select> 

¿Por qué hace esto? Bueno, si tiene 50 tipos de entidades, cada una con algún tipo de selección de diferentes valores, simplemente evitó crear 50 ViewModels adicionales.