Pregunta

Acabo de encontrar un efecto interesante al depurar una vista. El escenario es fácil de reproducir: tengo un punto de ruptura en un View, en la ventana de reloj que agrego ViewBag.ViewData y el valor es null. Sin embargo, si solo agrego ViewBag y expandir el objeto, puedo ver el ViewData y no es null. También puedo expandirlo con éxito y ver sus propiedades.

¿Alguien puede explicar si es un error o qué causa este comportamiento?

ViewBag.ViewData in Watch window

EDITAR

ViewBag.ViewData es en realidad null. Por ejemplo, si tengo este código en la vista:

if (ViewBag.ViewData == null)
{
    <span>ViewBag.ViewData is null</span>
}

Muestra el tramo. Entonces, la parte extraña es que puedo expandirlo en la ventana del reloj y ver las propiedades.

Edición2

En respuesta a la respuesta de @darin dimitrov: intenté reproducir este comportamiento con una clase de prueba personalizada y obtengo un RuntimeBinderException Al intentar acceder a la propiedad privada: 'SomeClass.SomeProperty' is inaccessible due to its protection level:

public class SomeClass
{
    private string SomeProperty;
}

dynamic dynamicObject = new SomeClass();
if (dynamicObject.SomeProperty == null)
{
    Console.WriteLine("dynamicObject.SomeProperty is null");
}

En este caso, ¿no debería obtener la misma excepción al acceder ViewBag.ViewData en la vista (la línea con if (ViewBag.ViewData == null))?

¿Fue útil?

Solución

Lo que ves en la ventana de depurador/reloj es el privado ViewData propiedad del ViewBag. Cuando realiza la prueba en la vista, obviamente no tiene acceso a este campo privado y se vuelve nulo porque no hay propiedad pública correspondiente.

Ahora haga la siguiente prueba en la vista:

@if (null == ViewBag
         .GetType()
         .GetProperty("ViewData", BindingFlags.Instance | BindingFlags.NonPublic)
         .GetValue(ViewBag, null)
)
{
    <span>ViewBag.ViewData is null</span>
}

Y no verás el tramo.

Por supuesto, todo esto es muy divertido, pero cuando se trata de escribir el mundo real y las aplicaciones ASP.NET MVC debidamente diseñadas ViewData y ViewBag no tengo lugar. Esos dos son mis peores enemigos en el desarrollo de aplicaciones ASP.NET MVC.

Conclusión: siempre use modelos de vista y vistas fuertemente escrita y diviértete.

Otros consejos

No tengo una explicación técnica, pero creo que es porque Viewbag es dinámico. Es como hacer un reloj en una expresión, no ves el contenido del conjunto de resultados sin ejecutar la expresión.

Supongo que la bolsa de vista se está comportando de la misma manera, porque vas directamente a una propiedad que no se ha cargado y lo estás haciendo a través de un depurador, simplemente decide no cargar esa propiedad.

Podría estar totalmente equivocado, por supuesto: D

Solo por el bien de los argumentos, ¿hace lo mismo en la observación rápida o en la ventana inmediata?

Si bien su código siempre se ejecuta dentro de los límites de cierto alcance (clase, método, privado, etc.), el depurador no tiene tales límites

¿Por qué hace referencia a ViewBag.ViewData? Simplemente haga referencia a ViewData directamente. Esto puede funcionar porque detrás de escena ViewBag usa ViewData, puede estar buscando una representación interna de ViewData, separado que su propiedad Dynamimc de "ViewData"

Después de probar esto, ViewBag aparece como miembro no público ... que es lo que esperaría. System.web.mvc.dynamicViewDatadictionary tiene un miembro de visualización de miembros públicos

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top