2

継承に関連するASP.NETMVC(MVC 2プレビュー2を使用しています)のModelBindingについて質問があります。

次のインターフェイス/クラスがあるとします。

interface IBase
class Base : IBase
interface IChild
class Child: Base, IChild

そして、カスタムモデルバインダーBaseModelBinderがあります。

次の問題はありません。

ModelBinders.Binders[typeof(Child)] = new BaseModelBinder();
ModelBinders.Binders[typeof(IChild)] = new BaseModelBinder();

以下は機能しません(Childタイプのonオブジェクトのバインドでは):

ModelBinders.Binders[typeof(Base)] = new BaseModelBinder();
ModelBinders.Binders[typeof(IBase)] = new BaseModelBinder();

すべての継承されたクラスに適用される基本クラスのモデルバインダーを作成する方法はありますか?可能なすべての継承クラスに対して手動で何かを入力する必要は本当にありません。

また、可能であれば、特定の継承クラスのモデルバインダーをオーバーライドする方法はありますか?これは機能しましたが、Child2用の特定のモデルバインダーが必要だったとします。

前もって感謝します。

4

2 に答える 2

6

リフレクションを使用して、起動時にすべての派生クラスを動的に登録するだけです。たぶんそれはきれいな解決策ではないかもしれませんが、初期化コードの数行だけが機能します;-)

しかし、本当にモデル バインダーをいじりたい場合は (最終的にはそうしなければならないでしょう、時間を費やすためのより良い方法があります ;-)、これこれを読むことができます。

于 2009-12-03T21:12:11.213 に答える
1

それを行う 1 つの方法は、ModelBindersDictionaryクラスをサブクラス化し、GetBinders(Type modelType, bool fallbackToDefault) メソッドをオーバーライドすることだと思います。

public class CustomModelBinderDictionary : ModelBinderDictionary
{
    public override IModelBinder GetBinder(Type modelType, bool fallbackToDefault)
    {
        IModelBinder binder = base.GetBinder(modelType, false);

        if (binder == null)
        {
            Type baseType = modelType.BaseType;
            while (binder == null && baseType != typeof(object))
            {
                binder = base.GetBinder(baseType, false);
                baseType = baseType.BaseType;
            }
        }

        return binder ?? DefaultBinder;
    }
}

基本的に、モデル バインダーが見つかるまで、またはデフォルトでDefaultModelBinder.

次のステップは、フレームワークにCustomModelBinderDictionary. 私が知る限り、次の 3 つのクラスをサブクラス化し、Binders プロパティをオーバーライドする必要があります: DefaultModelBinderControllerActionInvokerおよびController. CustomModelBinders独自の静的クラスを提供したい場合があります。

免責事項: これは大まかなプロトタイプです。それが実際に機能しているかどうか、それがどのような影響を与える可能性があるか、またはそれが健全なアプローチであるかどうかはわかりません. フレームワークのコードを自分でダウンロードして実験することもできます。

更新

別の解決策は、独自の を定義することだと思いますCustomModelBindingAttribute

public class BindToBase : CustomModelBinderAttribute
{
    public override IModelBinder GetBinder()
    {
        return new BaseModelBinder();
    }
}

public class CustomController
{
   public ActionResult([BindToBase] Child child)
   {
       // Logic.
   }
}
于 2009-12-02T21:02:34.690 に答える