有没有办法用一行代码创建一个带有模型和附加属性的ViewDataDictionary
。我试图在组装模型和一些额外的显示配置属性时对强类型视图进行RenderPartial
调用,而无需跨多行显式组装ViewDataDictionary。似乎有可能在RenderPartial
重载同时采用模型object
和ViewDataDictionary
,但看起来只要它们都被填充就会忽略ViewDataDictionary
。
// FAIL: This will result in ViewData being a ViewDataDictionary
// where Model = MyModelObject and there are no other parameters available.
this.Html.RenderPartial("SomePartialView", MyModelObject, new ViewDataDictionary(new { SomeDisplayParameter = true }));
我找到了same problem的其他人,但他们的解决方案与我找到的相同的多线概念:使用模型创建离散ViewDataDictionary
,添加新参数并使用它在RenderPartial
电话中。
var SomeViewData = new ViewDataDictionary(MyModelObject);
SomeViewData.Add("SomeDisplayParameter", true);
this.Html.RenderPartial("SomePartialView", SomeViewData);
我总是可以将这个逻辑包装成一个ChainedAdd
方法,该方法返回一个重复的字典,并添加了新的元素,但似乎我错过了一些创建ViewDataDictionary
的方法来实现这一点我(这比我希望的要多一点)。
this.Html.RenderPartial("SomePartialView", new ViewDataDictionary(MyModelObject).ChainedAdd("SomeDisplayParameter", true));
public static ViewDataDictionaryExtensions {
public static ViewDataDictionary ChainedAdd(this ViewDataDictionary source, string key, object value) {
return source.ChainedAdd(new KeyValuePair<string,object>(key, value));
}
public static ViewDataDictionary ChainedAdd(this ViewDataDictionary source, KeyValuePair<string, object> keyAndValue) {
ViewDataDictionary NewDictionary = new ViewDataDictionary(source);
NewDictionary.Add(keyAndValue);
return NewDictionary;
}
}
同样,尝试使用显式ViewDataDictionary
和Model
组装ModelState
只会导致编译错误,因为ModelState是只读的。
// FAIL: Compilation error
this.Html.RenderPartial("SomePartialView", new ViewDataDictionary { Model = MyModelObject, ModelState = new ViewDataDictionary( new { SomeDisplayParameter = true }});
ANSWER(S):看起来像Craig和我最终找到了两个单独的语法来完成工作。在这种情况下我肯定有偏见,但我喜欢先设置模型然后“装饰”它的想法。
new ViewDataDictionary(MyModelObject) { { "SomeDisplayParameter", true }, { "SomeOtherParameter", 3 }, { "SomeThirdParameter", "red" } };
new ViewDataDictionary(new ViewDataDictionary() { {"SomeDisplayParameter", true }})
{ Model = MyModelObject };
当然,如果没有他的[最终定点]答案,我仍然会旋转我的车轮,所以,圆圈得到了正方形。
答案 0 :(得分:26)
使用object initializer和集合初始值设定项:
new ViewDataDictionary(new ViewDataDictionary() { {"SomeDisplayParameter", true }})
{
Model = MyModelObject
}
内部ViewDataDictionary初始化其集合,然后使用构造函数重载填充“真正的”ViewDataDictionary,该重载采用ViewDataDictionary而不是object。最后,对象初始化器设置模型。
然后在不分别设置MyModelObject的情况下传递整个事物:
this.Html.RenderPartial("SomePartialView", null,
new ViewDataDictionary(new ViewDataDictionary() { {"SomeDisplayParameter", true }})
{ Model = MyModelObject });
答案 1 :(得分:12)
使用Craig的答案作为起点 - 我甚至不知道你可以将构造函数调用和对象初始化程序结合起来 - 我偶然发现了来自Palermo的这个snippet,这导致了一个有效的组合。他使用某种字典速记,在ModelState
对象初始值设定项使用时会以某种方式填充ViewDataDictionary
。
new ViewDataDictionary(MyModelObject) { { "SomeDisplayParameter", true }, { "SomeOtherParameter", 3 }, { "SomeThirdParameter", "red" } };
// Of course, this also works with typed ViewDataDictionary objects (what I ended up using)
new ViewDataDictionary<SomeType>(MyModelObject) { { "SomeDisplayParameter", true }, { "SomeOtherParameter", 3 }, { "SomeThirdParameter", "red" } };
鉴于您无法在初始化程序中明确设置ModelState
,我仍然看不到这最终是如何工作的,但它似乎确实维护了原始模型对象和视图的“附加”参数。这种语法肯定有许多其他的排列不起作用 - 你不能将模型与单个对象中的字典结合使用,或者使用对象初始化器语法来表示字典值 - 但上述版本似乎有效。 / p>
答案 2 :(得分:2)
我在HtmlHelper上创建了一个扩展方法,将属性名称和值从匿名对象复制到ViewDataDictionary。
<强>示例强>
Html.RenderPartial("SomePartialView", MyModelObject, new { SomeDisplayParameter = true })
HtmlHelper Extension
public static void RenderPartial(this HtmlHelper htmlHelper, string partialViewName, object model, object viewData)
{
var vdd = new ViewDataDictionary(model);
foreach (var property in viewData.GetType().GetProperties()) {
vdd[property.Name] = property.GetValue(viewData);
}
htmlHelper.RenderPartial(partialViewName, vdd);
}
答案 3 :(得分:0)
我带着完全相同的问题来到这里。
我认为可能有用(请原谅VB Razor语法)
@Code Html.RenderPartial("Address", Model.MailingAddress, New ViewDataDictionary(New With {.AddressType = "Mailing Address"}))End Code
但是你当然会在运行时遇到这个错误:
System.InvalidOperationException未被用户代码
处理Message =传入字典的模型项类型为'VB $ AnonymousType_1`1 [System.String]',但此字典需要“ViewModel.Address”类型的模型项。
但我发现,无论如何,我真正想要使用的是编辑模板。
而不是使用RenderPartial:
@Html.EditorFor(Function(model) model.MailingAddress, "Address", New With {.AddressType = "Mailing Address"})
编辑器模板只是一个生活的部分视图
〜/查看/ {型号|共享} /EditorTemplates/templatename.vbhtml
我的Address模板是强类型的局部视图,但EditorFor方法可以使用anon对象轻松添加其他视图数据项。
在上面的示例中,我不需要包含模板名称“Address”,因为MVC会查找与模型类型同名的模板。
您也可以用同样的方式覆盖显示模板。
答案 4 :(得分:0)
这对我来说在老式的mvc aspx视图中起作用了:
<% Html.RenderPartial("ContactPartial", Model.ContactFactuur, new ViewDataDictionary(this.ViewData ) { TemplateInfo = new TemplateInfo { HtmlFieldPrefix = "Factuur" } }); %>
这里的事情是在构造函数中我使用当前的viewdata&#34; new ViewDataDictionary(this.ViewData)&#34;这是一个viewdatadictionary,包含验证消息所需的模型状态。