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 開発者は最初に何もチェックする必要がないため、より多くの作業が必要になります。

でも、やっぱりこれが原因です。

*これが、私のクラスで動作するコレクションへのバインドの例を取得できなかった理由でもあります。これらは配列ではありませんが、IEnumerable<> や IDictionary<> でもありません。私が思うさらに別のバグ。

于 2012-07-30T19:13:15.150 に答える