1

我有一个自定义模型绑定器,它继承了看起来像这样的 DefaultModelBinder。

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 mvc gridview)并将网格中的控件绑定到项目列表。

如果我使用派生自 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 创建并返回常规集合的模型吗?

4

1 回答 1

2

我查看了 DefaultModelBinder 的来源并找出了问题所在。

在 BindComplexModel 方法的 DefaultModelBinder 中,如果类型不是数组并且是通用 IEnumerable ( IEnumerable<>) 并且它是 ICollection<> 的实例,它将调用 UpdateCollection。由于所述的所有原因,它无法填充集合。因为 count = 0,UpdateCollection 方法返回 null。因此,我从 ICollection 派生的类(例如 BindingList)将具有这种行为。

但是,我的自定义集合实际上源自旧的 CollectionBase 类(并且它单独实现了通用的 IEnumerable)。这意味着 BindComplexModel 不会尝试填充集合,而是像往常一样绑定到对象。*

我个人认为这是一个错误或至少是一个疏忽。如果您绑定到一个集合并且表单有 0 个项目(例如用户已删除所有行),您将不会从默认绑定中得到任何回报。但是你不应该只得到零项目的集合吗?什么都不返回的原因是什么?这给 MVC 开发人员带来了更多的工作,因为现在他们必须先检查什么。

但无论如何,这就是原因。

*And this is also the reason I couldn't get the examples of binding to collections to work with my classes. They are not arrays but neither are they IEnumerable<> or IDictionary<>. Yet another bug I think.

于 2012-07-30T19:13:15.150 回答