And*_*i V 6 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
}
Run Code Online (Sandbox Code Playgroud)
一切运作良好:模板切换到适当的类型模板,在我可以访问Metadata属性的内部:
string name = ViewData.ModelMetadata.PropertyName;
string controllerName = ViewData.ModelMetadata.ContainerType.Name;
//render property accordingly (using the property information)
Run Code Online (Sandbox Code Playgroud)
但是,如果由于某种原因ViewBag包含与其中一个属性同名的(动态)Model属性,ModelMetadata则不会完全生成; 至少上述ModelMetadata属性设置为null.例如,如果在我设置的控制器中ViewBag.ProductName = myModel.ProductName;,当ProductName属性进入其相应的模板时,元数据不包含"预期"值.
该解决方案很简单:如果,不管出于什么原因,物业需要保存的ViewBag,它必须以不同的名称保存.
我的问题是:如何EditorHelper将数据传递给模板?我不希望这样,ViewData并ViewBag"分享"这些信息.与检查快速监视我可以看到在Non-Public members中的ViewBag一个ViewData这似乎是一样的性质,可以说,一般可用ViewData对象.为什么不完全独立?
你的问题有一个非常简单的答案:
ViewBag是 的动态包装器ViewData。它们实际上是同一件事。你放入的任何东西ViewData也会放入ViewBag,反之亦然。
您可以在此处查看 的实现DynamicViewDataDictionary(这是其ViewBag实例)。正如您所看到的,它只是保存对其包装的内部引用并将属性访问委托给字典元素。ViewDataDictionary
因此,当框架传递ViewData到具有特定键的模板并且您分配ViewBag具有匹配名称的属性时,只有一个可以获胜。
硬币的另一面 - 我认为实际上更相关 - 是负责ModelMetadata提供元数据检查的静态方法ViewData 首先检查 - 在检查模型对象的元数据之前。
因此,如果您将属性分配给ViewBag(并且 - 通过关联 - ViewData),这些属性将与您传递给模板的表达式相匹配,并且这些属性不会具有某些元数据,例如模型类上的数据注释提供的元数据。
| 归档时间: |
|
| 查看次数: |
375 次 |
| 最近记录: |