c# - EditorHelper 是否使用 ViewBag 将数据传递给相应的模板?

标签 c# asp.net-mvc templates razor

我在覆盖 Object.cshtm 模板时观察到一些奇怪的行为。 Object.cshtm 迭代 Model 属性并将它们“发送”到适当的模板进行呈现。

foreach (var prop in ViewData.ModelMetadata.Properties)        
{
    @Html.Editor(prop.PropertyName, 
          "MyCustomTemplateCollection" + prop.TemplateHint) 
    //TemplateHint set by custom attributes
}

一切正常:模板切换到适当的类型模板,在我可以访问的模板中 Metadata 属性:

string name = ViewData.ModelMetadata.PropertyName;
string controllerName = ViewData.ModelMetadata.ContainerType.Name;

//render property accordingly (using the property information)

但是,如果由于某种原因 ViewBag 包含一个与 Model 属性之一同名的(动态)属性,则 ModelMetadata 未完全生成;至少上述 ModelMetadata 属性设置为 null。例如,如果在我的 Controller 中我设置了 ViewBag.ProductName = myModel.ProductName;,当 ProductName 属性进入其对应的模板时,元数据不包含“预期的” "值(value)观。

解决方案非常简单:如果出于某种原因,属性需要保存在ViewBag 中,则必须以不同的名称保存。

我的问题是:EditorHelper 如何将数据传递给模板?我不希望 ViewDataViewBag “共享”此类信息。使用 QuickWatch 检查我可以在 ViewBagNon-Public members 中看到一个 ViewData 属性,它似乎是与一般可用的 ViewData 对象相同。为什么不完全独立?

最佳答案

您的问题有一个非常简单的答案:

ViewBagViewData 的动态包装器。它们实际上是同一件事。您放入 ViewData 中的所有内容也会放入 ViewBag 中,反之亦然。

您可以看到DynamicViewDataDictionary 的实现(ViewBag 是它的一个实例)here .如您所见,它只是持有对其包装的 ViewDataDictionary 的内部引用,并将属性访问委托(delegate)给字典元素。

因此,当框架将 ViewData 传递到具有特定键的模板中并且您分配具有匹配名称的 ViewBag 属性时,只有一个可以获胜。

硬币的另一面 - 我认为实际上更相关 - 是负责提供元数据检查的静态 ModelMetadata 方法首先检查 ViewData - 在检查模型对象的元数据之前。

因此,如果您将属性分配给 ViewBag(以及 - 通过关联 - ViewData),这些属性将与您传递给模板的表达式相匹配并且这些不会有某些元数据,例如模型类上的数据注释提供的元数据。

关于c# - EditorHelper 是否使用 ViewBag 将数据传递给相应的模板?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20514573/

相关文章:

asp.net-mvc - Entity Framework Include OrderBy随机生成重复数据

c++ - 如何通用地编写隐藏结构的属性? (C++ 的设计/实现)

c++ - 如何重新排序功能参数?

c# - 使用 Visual Studio 调试器查看/诊断内存转储中的逻辑 .NET 线程

javascript - Div在asp.net中显示无/隐藏javascript函数

asp.net-mvc - 将backbone.js 与ASPNET MVC 集成是否有意义?

ruby - 如何全局指定Middleman的partials目录?

c# - 如何将所有硬币从 3D 空间移动到 2D Canvas 的一角

c# - 简单泛型类型比较

c# - 尽管安装了 Entity Framework v6.1.3,但仍无法访问 System.Data.Entity 命名空间?