我的ViewData如何无效,但在调试器中可以扩展?
-
26-10-2019 - |
题
在调试视图时,刚刚遇到了一个有趣的效果。场景易于复制 - 我有一个断点 View
, ,在手表窗口中我添加 ViewBag.ViewData
价值是 null
. 。但是,如果我只是添加 ViewBag
并扩展对象,我可以看到 ViewData
不是 null
. 。我还可以成功扩展它并查看其属性。
谁能解释这是错误还是导致这种行为的原因?
编辑
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应用程序时 ViewData
和 ViewBag
没有地方。这两个是我在ASP.NET MVC应用程序开发中最差的敌人。
结论:始终使用视图模型和强烈键入的观点并获得乐趣。
其他提示
我没有技术解释,但我相信这是因为ViewBag是动态的。这就像在表达式上手表一样,您在不运行表达式的情况下看不到结果集的内容。
我想ViewBag的行为方式相同,因为您直接进入尚未加载的属性,并且您正在通过调试器进行操作,它只是决定不加载该属性。
我当然可能完全错了:D
仅出于争论,它是否在快速观看或直接窗口中执行相同的操作?
虽然您的代码始终在某些范围(类,方法,私有等)的范围内运行,但调试器没有此类限制
您为什么引用viewbag.viewdata?只需直接引用ViewData。这可能会起作用,因为在幕后viewbag使用ViewData,您可能正在查看ViewData的内部表示,而不是“ ViewData”的Dynamimc属性分开
测试此内容后,ViewBag显示为非公开会员……这是我所期望的。 system.web.mvc.dynamicviewdaticticary有一个非公共成员ViewData