2013-05-30 168 views
1

我已經看到了一些類似的問題,但似乎沒有一個答案讓我比我更進一步。ASP.NET MVC 4 - 複雜類型和模型綁定/渲染

我有一個ViewModel,它包含一些代表某些股票UI控件的複雜類型,並附加了一些驗證邏輯。我需要將這些渲染到基於EditorTemplate/DisplayTemplate的頁面,並且還需要在提交表單時正確綁定屬性,以便開發人員可以在其控制器內使用視圖模型等。

簡單示例這是

public class TestViewModel 

{ 
    public HierarchyField MyField {get; set; } 
} 

在它的最簡單的,我需要的開發人員能夠創建此視圖模型編輯器具有簡單

@Html.EditorForModel() 

而對於hierarchyField給任何可編輯的部分,字段是設置在一個cust該類型的EditorTemplate。

我已經儘可能地通過使用自定義的MetaDataProvider和重寫IsComplexType來完成這個任務,儘管這不是我完全熟悉的事情,但是完成這項工作。該解決方案的細節在這裏(http://blogs.msdn.com/b/stuartleeks/archive/2010/04/01/collections-and-asp-net-mvc-templated-helpers-part-3.aspx?Redirected=true

我現在堅持試圖讓模型綁定更新在提交表單的財產,並呼籲hierarchyField給類中的方法來執行一個小自定義驗證和更新基於該調用結果的ModelState。

我首先創建了一個DefaultModelBinder的子類,它有BindProperty覆蓋內的邏輯來檢查綁定的屬性是否屬於這種類型。迄今爲止都很好。問題出現在我想調用採用預期值並試圖驗證該值的實例方法時。 BindProperty方法爲我提供了一個PropertyDescriptor實例,它允許我找到關於我的屬性的元數據,以及一個帶ValueProvider的BindingContext,它允許我讀取值,但是,沒有從我的複雜類型返回的實例:

bindingContext.ValueProvider.GetValue(propertyDescriptor.Name + ".Value") 

凡propertyDescriptor.Name +「.value的」等同於事實,在我的EditorTemplate我有以下幾點:

@Html.TextBoxFor(model => model.Value) 

相反的類型,因爲我明明只有到了價值的參考在發佈的字段中的屬性,我得到一個String []。我假設,爲了實現這一點,我需要爲HierarchyField註冊某種ValueProvider,但理想情況下我正在尋找一些更通用的東西,因爲我有許多這些類型可以設置,所有其中的子類是一個通用的抽象類型(它們都有一個名爲'Value'的屬性,它返回它們的值的字符串表示)。

如果我說實話,整個過程看起來非常痛苦,我覺得我錯過了很簡單的事情。不幸的是,我確實需要這是通用的,因爲有幾十個這樣的字段,而且我確實需要這個模型,或者類似的字段來處理它們的驗證,而這些無法通過DataAnnotation驗證屬性完成。我無法創建與特定視圖模型綁定的自定義代碼,我寧願最小化與特定字段綁定的代碼,也不希望將某些適用於基類(FieldBase)及其任何子類的代碼優化。

很高興發佈其他代碼,如果有人需要看到它。

回答

6

我一直在一些項目中使用複雜的類型和自定義渲染沒有任何問題。也許我誤解了你的問題,但我想我可以發佈一個簡化的工作示例(MVC4),也許它會幫助你的方式。

[ComplexType] 
public class AccessType 
{ 
    public bool ReadAccess { get; set; } 
    public bool EditAccess { get; set; } 
} 

該模型被定義爲::

在我的例子爲複雜類型定義

public class UserAccess 
{ 
    [Key] 
    public Int32 UserId { get; set; } 
    public AccessType AccessType { get; set; } 
} 

我已經創建了以下顯示模板視圖\共享\ DisplayTemplates命名爲AccessType.cshtml來處理複雜類型的顯示。

@model [path to complex type].AccessType 
@Html.LabelFor(m => m.EditAccess,"Read access") 
@Html.DisplayFor(m => m.ReadAccess) 
@Html.LabelFor(m => m.EditAccess, "Edit access") 
@Html.DisplayFor(m => m.EditAccess) 

我創建了一個查看\共享\ EditorTemplates命名AccessType.cshtml來處理複雜類型的渲染時,它正在編輯以下編輯模板

@model [path to complex type].AccessType 
@Html.LabelFor(m => m.ReadAccess,"Read access") 
@Html.CheckBoxFor(m => m.ReadAccess) 
@Html.LabelFor(m => m.EditAccess, "Edit access") 
@Html.CheckBoxFor(m => m.EditAccess) 

要使用這個複雜類型,我做了如下修改模型視圖文件:

_CreateOrEdit.cshtml文件我已經添加了此行來呈現複合型部分:

@Html.EditorFor(m => m.AccessType) 

...到Delete.cshtmlDetails.cshtml我說:

@Html.DisplayFor(m => m.AccessType) 

...和Index.cshtml我說:

@Html.DisplayFor(_ => item.AccessType) 

這是我所需要的渲染和使用複雜類型。

如果你的問題更復雜,那麼請添加一些更多的代碼來說明。