在调试View时遇到了一个有趣的效果。该场景很容易重现 - 我在View
中有一个断点,在Watch窗口中我添加了ViewBag.ViewData
,值为null
。但是,如果我只是添加ViewBag
并展开对象,则可以看到ViewData
,而不是null
。我也可以成功扩展它并查看它的属性。我的ViewData如何可以为null,但在调试器中可扩展?
任何人都可以解释是否它是一个错误或导致此行为的原因?
编辑
ViewBag.ViewData
实际上是null
。例如。如果我在视图中有这样的代码:
if (ViewBag.ViewData == null)
{
<span>ViewBag.ViewData is null</span>
}
它显示跨度。所以奇怪的部分是我可以在观察窗口中展开它并查看属性。
EDIT2
针对@Darin季米特洛夫的答案 - 我试图重现一个自定义的测试类这种行为,我得到一个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");
}
在这种情况下,在视图(if (ViewBag.ViewData == null)
的行中)中访问ViewBag.ViewData
时,我是不是应该得到相同的异常?
感谢您的回答,它似乎是目前为止似乎最合理的解释(除了Watch/Debugger中的错误)。但是,当我尝试访问'ViewBag.ViewData'(请参阅** EDIT2 **到我的问题)时,我不应该得到'RuntimeBinderException'而不是'null'?顺便说一句,我很感激你提醒ViewBag和ViewData的邪恶,但这不是必要的 - 我自己强烈支持强类型的视图模型;) – Yakimych 2011-04-28 22:07:04
@Yakimych,你的EDIT2并不符合ASP.NET中的真实情况MVC。看看框架的源代码。你会发现从'DynamicObject'派生出来的'System.Web.Mvc.DynamicViewDataDictionary'类型,并且覆盖ViewBag所具有的获取和设置属性。在EDIT2中,您只需将动态值设置为“SomeClass”。我建议你下载并探索ASP.NET MVC的源代码,以深入理解内部运作。 – 2011-04-28 22:15:01
是的,正好 - 当您发布此评论时,我正在查看源代码。 'DynamicViewDataDictionary'继承'DynamicObject'并通过覆盖'TryGetMember'和'TrySetMember'来覆盖默认的'dynamic'行为。没有深入细节,但这最终是有道理的。感谢您满足我的好奇心! +1并接受答案! – Yakimych 2011-04-28 22:29:24