7

刚刚在调试视图时遇到了一个有趣的效果。该场景很容易重现 - 我在View我添加的 Watch 窗口中有一个断点,ViewBag.ViewData值为null. 但是,如果我只是添加ViewBag和扩展对象,我可以看到ViewDataand it is not null。我还可以成功扩展它并查看它的属性。

谁能解释这是一个错误还是导致这种行为的原因?

观察窗口中的 ViewBag.ViewData

编辑

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

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

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

编辑2

作为对@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");
}

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

4

4 回答 4

6

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

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

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

你不会看到跨度。

当然,这一切都很有趣,但是在编写真实世界和正确架构的 ASP.NET MVC 应用程序时,两者ViewDataViewBag没有位置。这两个是我在 ASP.NET MVC 应用程序开发中最大的敌人。

结论:总是使用视图模型和强类型视图,并且玩得开心。

于 2011-04-28T18:49:44.677 回答
0

我没有技术解释,但我相信这是因为 ViewBag 是动态的。这就像对表达式进行监视一样,如果不运行表达式,您将看不到结果集的内容。

我猜 ViewBag 的行为方式相同,因为您将直接转到尚未加载的属性,并且您正在通过调试器进行操作,它只是决定不加载该属性。

当然,我可能完全错了:D

只是为了争论,它在快速观看或即时窗口中是否做同样的事情?

于 2011-04-28T12:32:05.573 回答
0

虽然您的代码始终在特定范围(类、方法、私有等)的限制内运行,但调试器没有这样的限制

于 2011-04-28T14:48:23.290 回答
0

为什么要引用 ViewBag.ViewData?直接引用 ViewData 即可。这可能会起作用,因为在幕后 viewbag 使用 viewdata,您可能正在查看 ViewData 的内部表示,与“ViewData”的动态属性分开

在对此进行测试后,ViewBag 以非公开成员的身份出现……这是我所期望的。System.Web.Mvc.DynamicViewDataDictionary 有一个非公共成员 ViewData

于 2011-04-28T14:51:53.793 回答