在调试视图时,刚刚遇到了一个有趣的效果。场景易于复制 - 我有一个断点 View, ,在手表窗口中我添加 ViewBag.ViewData 价值是 null. 。但是,如果我只是添加 ViewBag 并扩展对象,我可以看到 ViewData 不是 null. 。我还可以成功扩展它并查看其属性。

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

ViewBag.ViewData in Watch window

编辑

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

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

它显示跨度。因此,怪异的部分是我可以在手表窗口中展开它并查看属性。

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");
}

在这种情况下,访问时我不应该得到同样的例外 ViewBag.ViewData 在视图中(与 if (ViewBag.ViewData == null))?

有帮助吗?

解决方案

您在调试器/手表窗口中看到的是 私人的 ViewData 属性 ViewBag. 。当您在视图中进行测试时,您显然无法访问此私有字段,并且由于没有相应的公共财产而获得无效。

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

@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应用程序开发中最差的敌人。

结论:始终使用视图模型和强烈键入的观点并获得乐趣。

其他提示

我没有技术解释,但我相信这是因为ViewBag是动态的。这就像在表达式上手表一样,您在不运行表达式的情况下看不到结果集的内容。

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

我当然可能完全错了:D

仅出于争论,它是否在快速观看或直接窗口中执行相同的操作?

虽然您的代码始终在某些范围(类,方法,私有等)的范围内运行,但调试器没有此类限制

您为什么引用viewbag.viewdata?只需直接引用ViewData。这可能会起作用,因为在幕后viewbag使用ViewData,您可能正在查看ViewData的内部表示,而不是“ ViewData”的Dynamimc属性分开

测试此内容后,ViewBag显示为非公开会员……这是我所期望的。 system.web.mvc.dynamicviewdaticticary有一个非公共成员ViewData

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top