26

有没有办法ViewDataDictionary用一行代码创建一个模型和附加属性。我试图RenderPartial在组装模型和一些额外的显示配置属性时调用强类型视图,而无需跨多行显式组装 ViewDataDictionary。RenderPartial考虑到同时采用模型object和 a的重载似乎是可能的,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 }));

我发现其他人有同样的问题,但他们的解决方案与我发现的多线概念相同: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使用显式组装 aModelModelState简单地导致编译错误,因为 ModelState 是只读的。

// FAIL: Compilation error
this.Html.RenderPartial("SomePartialView", new ViewDataDictionary { Model = MyModelObject, ModelState = new ViewDataDictionary( new { SomeDisplayParameter = true }});

回答(S):看起来克雷格和我最终找到了两种不同的语法来完成工作。在这种情况下,我肯定是有偏见的,但我喜欢先设置模型然后“装饰”它的想法。

new ViewDataDictionary(MyModelObject) { { "SomeDisplayParameter", true }, { "SomeOtherParameter", 3 }, { "SomeThirdParameter", "red" } };

new ViewDataDictionary(new ViewDataDictionary() { {"SomeDisplayParameter", true }})
    { Model = MyModelObject };

当然,如果没有他[最终准确]的回答,我仍然会旋转我的轮子,所以,圆圈得到了正方形。

4

5 回答 5

26

使用对象初始化器和集合初始化器:

new ViewDataDictionary(new ViewDataDictionary() { {"SomeDisplayParameter", true }})
    {
        Model = MyModelObject
    }

内部 ViewDataDictionary 初始化其集合,然后使用构造函数重载填充“真实” ViewDataDictionary,该构造函数重载采用 ViewDataDictionary 而不是对象。最后,对象初始化器设置模型。

然后只需传递整个事情而不单独设置 MyModelObject :

this.Html.RenderPartial("SomePartialView", null, 
    new ViewDataDictionary(new ViewDataDictionary() { {"SomeDisplayParameter", true }})
        { Model = MyModelObject });
于 2009-03-03T20:26:02.717 回答
12

使用 Craig 的答案作为起点——我什至不知道你可以将构造函数调用和对象初始化程序结合起来——我偶然发现了来自巴勒莫的这个片段,它导致了一个有效的组合。他使用某种字典速记,以某种方式最终填充对象初始值设定项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在初始化程序中显式设置,我仍然看不到这最终是如何工作的,但它似乎确实同时维护了原始模型对象和视图的“附加”参数。这种语法肯定有许多其他排列不起作用 - 您不能将模型与字典组合在单个对象中,或者对字典值使用对象初始化器语法 - 但上述版本似乎有效。

于 2009-03-04T15:04:51.297 回答
2

我在 HtmlHelper 上创建了一个扩展方法,用于将属性名称和值从匿名对象复制到 ViewDataDictionary。

样本

Html.RenderPartial("SomePartialView", MyModelObject, new { SomeDisplayParameter = true })

HtmlHelper 扩展

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);
}
于 2014-06-26T21:59:21.447 回答
1

这在旧式 mvc aspx 视图中对我有用:

<% Html.RenderPartial("ContactPartial", Model.ContactFactuur, new ViewDataDictionary(this.ViewData ) { TemplateInfo = new TemplateInfo { HtmlFieldPrefix = "Factuur" } }); %>

这里的问题是,在构造函数中,我使用了当前的视图数据“new ViewDataDictionary(this.ViewData)”,这是一个包含验证消息所需的模型状态的视图数据字典。

于 2014-11-22T15:42:31.953 回答
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"})

编辑器模板只是存在的部分视图

~/Views/{Model|Shared}/EditorTemplates/templatename.vbhtml

我的 Address 模板是一个强类型的局部视图,但是 EditorFor 方法提供了使用匿名对象轻松添加其他视图数据项的能力。

在上面的示例中,我不需要包含模板名称“地址”,因为 MVC 会查找与模型类型同名的模板。

您也可以以相同的方式覆盖显示模板。

于 2012-10-20T20:17:39.743 回答