我有一个自定义模型绑定器,它继承了看起来像这样的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创建并返回常规集合的模型?
答案 0 :(得分:1)
我查看了DefaultModelBinder的源代码并找出了问题。
在BindComplexModel方法的DefaultModelBinder中,如果类型不是数组并且是通用IEnumerable(IEnumerable&lt;&gt;)并且它是ICollection的实例&lt;&gt;它将调用UpdateCollection。由于所述的所有原因,它无法填充集合。因为count = 0,UpdateCollection方法返回null。所以我从ICollection派生的类(例如BindingList)会有这种行为。
但是我的自定义集合实际上是从旧的CollectionBase类派生的(并且它实现了通用的IEnumerable分离)。这意味着BindComplexModel不会尝试填充集合,而只是正常绑定到对象。*
我个人认为这是一个错误或至少是疏忽。如果您绑定到一个集合并且该表单有0个项目(比如用户已删除所有行),您将无法从默认绑定中获得任何内容。但是你不应该只收集零项目的集合吗?没有回来的原因是什么?这为MVC开发人员提供了更多的工作,因为他们现在必须先检查一下。
但无论如何这就是原因。
*这也是我无法获得绑定到集合的示例以使用我的类的原因。它们不是数组,但它们都不是IEnumerable&lt;&gt;或IDictionary&lt;&gt;。我认为还有另一个错误。