2012-07-27 38 views
0

我有一個自定義模型綁定器,它繼承了看起來像這樣的DefaultModelBinder。BindModel在綁定到列表/集合(但不綁定到csla集合時)時返回null

Public Class GridFormBinder : Inherits DefaultModelBinder 

Public Overrides Function BindModel(controllerContext As System.Web.Mvc.ControllerContext, bindingContext As System.Web.Mvc.ModelBindingContext) As Object 
    Dim result As Object = MyBase.BindModel(controllerContext, bindingContext) 

    'Code to handle special case for grid/List binding. 

    Return result 
End Function 
End Class 

我之所以有這樣的定製綁定是我在網格中呈現項目的各種列表(使用的DevExpress GridView的MVC),我綁定控件在網格中的項目清單。

如果我使用派生自BusinessCollectionBase的類(來自非常改進的CSLA框架類),那麼所有的工作都和我想要的完全一樣。 BusinessCollectionBase從一類,看起來像派生...

<Serializable()> Public MustInherit Class BindableCollectionBase(Of T As IBusinessData) 
     Inherits CollectionBase 
     Implements IBindingList 
     Implements System.Collections.Generic.IEnumerable(Of T) 

但是,如果我綁定到,比方說,從BindingList<Customer>繼承的類的MyBase.BindModel(controllerContext, bindingContext)一直沒有返回。我已經嘗試了各種通用和非通用的BCL集合,並且BindModel方法始終返回null。

有什麼我必須做的,讓DefaultModelBinder創建並返回常規集合模型?

回答

1

我查看了DefaultModelBinder的源代碼並找出了問題。

在BindComplexModel方法中的DefaultModelBinder中,如果類型不是數組並且是通用IEnumerable(IEnumerable <>)並且它是ICollection的實例<>它將調用UpdateCollection。出於所有陳述的原因,它無法填充集合。因爲count = 0,UpdateCollection方法返回null。所以我從ICollection派生出來的類(例如BindingList)會有這種行爲。

但是我的自定義集合實際上是從舊的CollectionBase類派生的(並且它實現了通用的IEnumerable seperatly)。這意味着BindComplexModel不會嘗試填充集合,而是隻是綁定到正常的對象。*

我個人認爲這是一個錯誤或至少是一個疏忽。如果你綁定到一個集合並且表單有0個項目(假設用戶已經刪除了所有的行),你將從默認綁定中得到任何回報。但是,你不應該只收集零件的收集?沒有返回的理由是什麼?這使MVC開發人員做了更多的工作,因爲現在他們必須首先檢查什麼。

但無論如何這就是爲什麼。

*這也是我無法獲得綁定到集合以使用我的類的示例的原因。它們不是數組,但它們也不是它們的IEnumerable> <>或IDictionary <>。還有一個錯誤,我想。