我的ViewData如何为空,但在调试器中是否可扩展?

Yak*_*ych 7 c# asp.net-mvc dynamic viewbag

在调试View时遇到了一个有趣的效果.这个场景很容易重现 - 我有一个断点View,在我添加的Watch窗口中ViewBag.ViewData,值是null.但是,如果我只是添加ViewBag和扩展对象,我可以看到ViewData它而不是null.我也可以成功扩展它并查看其属性.

任何人都可以解释这是一个错误或是什么原因导致这种行为?

Watch窗口中的ViewBag.ViewData

编辑

ViewBag.ViewData实际上是null.例如,如果我在视图中有此代码:

if (ViewBag.ViewData == null)
{
    <span>ViewBag.ViewData is null</span>
}
Run Code Online (Sandbox Code Playgroud)

它显示跨度.所以奇怪的是我可以在观察窗口中展开它并查看属性.

EDIT2

为了回应@Darin Dimitrov的回答 - 我尝试使用自定义测试类重现此行为,并RuntimeBinderException在尝试访问私有属性时获得'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");
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,ViewBag.ViewData在View中访问时,我不应该得到相同的异常(行if (ViewBag.ViewData == null))吗?

Dar*_*rov 6

你在调试器/监视窗口看到的是私有 ViewData属性ViewBag.当您在视图中进行测试时,您显然无法访问此私有字段,并且您将获得null,因为没有相应的公共属性.

现在在视图中执行以下测试:

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

你不会看到跨度.

当然,这一切都是很可笑的,但是当涉及到写现实世界和正确设计ASP.NET MVC应用程序都ViewDataViewBag有没有地方.这两个是我在ASP.NET MVC应用程序开发中最糟糕的敌人.

结论:始终使用视图模型和强类型视图并获得乐趣.