2009-03-03 15 views
25

有沒有什麼辦法用一行代碼創建帶有模型和附加屬性的ViewDataDictionary。我試圖在調用強類型視圖時調用RenderPartial,同時組裝模型和一些額外的顯示配置屬性,而不用在多行中顯式組裝ViewDataDictionary。看來如果RenderPartial過載同時出現在模型objectViewDataDictionary上,但它看起來好像只是在它們都被填充時忽略了ViewDataDictionary用模型和ViewData項創建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與模型,添加新的參數(S),並在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有一個明確的ModelModelState只是導致編譯錯誤,因爲ModelState中是隻讀的。

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

ANSWER(S):它看起來像克雷格和我最終找到兩個單獨的語法,將完成這項工作。在這種情況下,我肯定有偏見,但我喜歡先設置模型並在之後「裝飾」模型。

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

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

當然,我仍然在旋轉我的車輪,而沒有[最終點亮]的答案,所以,圓形會得到廣場。

回答

25

使用object initializer和集合初始化:

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 }); 
+0

看起來這會創建一個ViewDataDictionary,其Model等於匿名對象,然後用MyModelObject替換Model屬性,而不留下任何附加屬性。它的確教會了我可以將構造函數與其他初始化方法結合起來;我不知道的 - 謝謝。 – patridge 2009-03-03 20:49:12

+0

我剛剛檢查了源代碼。設置模型不會清除字典。 – 2009-03-03 21:03:57

12

使用克雷格的答案作爲起點 - 我甚至不知道你可以結合兩種構造函數調用和對象initializer--我偶然發現了巴勒莫的這個snippet,這導致了一個可行的組合。他使用某種字典簡寫形式,當被對象初始值設定項消耗時,它以某種方式結束填充ModelState

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明確的初始化,但它似乎既保持原有的模型對象和視圖的「附加」參數。這個語法中肯定有很多其他的排列組合 - 你不能將模型與單個對象中的字典結合起來,或者使用字典值的對象初始化語法 - 但上面的版本似乎可行。

0

我來到這裏的確切同一個問題。

我認爲可能的工作是這個(原諒VB剃刀語法)

@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會查找與模型類型名稱相同的模板。

您也可以用相同的方式覆蓋顯示模板。

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); 
} 
0

這是我在老式什麼工作MVC ASPX觀點:

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

這裏的事情是,在騙子結構我使用當前viewdata「新ViewDataDictionary(this.ViewData)」這是一個viewdatadictionary包含模型狀態,我需要的驗證信息。