Question

Juste est tombé sur un effet intéressant lors du débogage une vue. Le scénario est facile à reproduire - je un point d'arrêt dans une View, dans la fenêtre Espion ajouter ViewBag.ViewData et la valeur est null. Cependant, si je viens d'ajouter ViewBag et développez l'objet, je peux voir la ViewData et ce n'est pas null. Je peux aussi développer avec succès et voir ses propriétés.

Quelqu'un peut-il expliquer que ce soit un bug ou ce qui provoque ce comportement?

ViewBag.ViewData dans la fenêtre Watch

EDIT

ViewBag.ViewData est en fait null. Par exemple. si je le code dans la vue:

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

il affiche la durée. Ainsi, la partie étrange est que je peux l'étendre dans la fenêtre de la montre et de voir les propriétés.

EDIT2

En réponse à la réponse de @Darin Dimitrov - J'ai essayé de reproduire ce comportement avec une classe de test personnalisé et je reçois un RuntimeBinderException lorsque vous essayez d'accéder à la propriété privée: '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");
}

Dans ce cas, je ne devrais pas être obtenir la même exception lors de l'accès ViewBag.ViewData dans la vue (la ligne avec if (ViewBag.ViewData == null))?

Était-ce utile?

La solution

Ce que vous voyez dans le débogueur / fenêtre montre est propriété privée ViewData du ViewBag. Lorsque vous faites le test dans la vue que vous avez évidemment pas accès à ce domaine privé et vous obtenez nul parce qu'il n'y a pas de propriété publique correspondante.

Maintenant faites le test suivant dans la vue:

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

et vous ne verrez pas la portée.

Bien sûr, tout cela est très drôle, mais quand il vient à l'écriture du monde réel et correctement les applications ASP.NET MVC architecturées à la fois ViewData et ViewBag n'a pas sa place. Ces deux sont mes pires ennemis dans le développement d'applications ASP.NET MVC.

Conclusion:. Toujours utiliser des modèles de vue et des vues fortement typées et vous amuser

Autres conseils

Je n'ai pas une explication technique, mais je crois qu'il est parce que ViewBag est dynamique. Il est comme faire une montre sur une expression, vous ne voyez pas le contenu du resultset sans courir l'expression.

Je suppose que le ViewBag se comporte de la même manière, parce que vous allez directement à une propriété qui n'a pas été chargé, et vous le faites à travers un débogueur, il décide tout simplement de ne pas charger cette propriété.

Je pourrais être tout à fait tort bien sûr: D

Juste pour l'amour arguments, fait-elle la même en montre rapide ou la fenêtre immédiate?

Alors que votre code fonctionne toujours dans les limites de certaines possibilités (classe, méthode, privée, etc.), le débogueur n'a pas de telles limites

Pourquoi parlez-vous ViewBag.ViewData? Il suffit de faire référence ViewData directement. Cela peut fonctionner parce que dans les coulisses de les utilisations vidéotex vous cherchez peut-être à une représentation interne de ViewData, séparez que votre propriété dynamimc de « ViewData »

Après avoir testé ceci, ViewBag montre en tant que membre non publiques ... qui est ce que j'attendais. System.Web.Mvc.DynamicViewDataDictionary a un membre non publique ViewData

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top