web-dev-qa-db-ja.com

ModelBinder属性とModelBinders.Add()の使用

誰かが[ModelBinder()]属性を使用することとglobal.asaxのModelBinders.Add()を介してモデルバインダーを登録することの長所/短所を教えてもらえますか?

私が考えることができる1つの利点は、それがより明示的であるのに対し、グローバルModelBindersに登録することは、アクションメソッドを検査する人にとってそれほど明白ではないということです。

私が考えることができる1つのトレードオフは、このモデルバインダーを使用する必要があるすべてのアクションメソッドにこの属性を追加する必要があるため、再利用できないことです。一方、グローバルModelBindersに登録すると、すべてのアクションで使用できるようになります。そのモデルを受け取るメソッド。

これが唯一の違いですか?

言い換えれば、これは正しいと言えますか?

  • モデルを1つのアクションメソッド(おそらく2つ、get + post)でのみ使用する場合は、[ModelBinder()]を使用します。
  • モデルを複数のアクションメソッドで使用する場合は、グローバルModelBindersに登録します。
24
Jerad Rose

これらのテクニックの結果は同じになるので、ほとんどの場合、チームがより快適に感じるかどうかの問題です。だからあなたはあなたが述べたような大会を思いつくことができます。

個人的には、そのモデルを使用するすべてのアクションメソッドに属性を設定する必要はありません。したがって、次のいずれかのオプションを選択します。

  • 次のようにモデルクラスに属性を設定します。

    _[ModelBinder(typeof(MyModelBinder))]
    public class MyModel
    {
        ...
    }    
    _
  • バインダーをグローバルに登録する

    _ModelBinders.Binders.Add(typeof(MyModel), new MyModelBinder())
    _

私がこれらのいずれかを好むもう1つの理由は、モデルバインディングプロセスを手動でトリガーする必要がある場合は、カスタムモデルバインダーも使用する必要があるためです。

_public ActionResult SomeActionMethod()
{
     MyModel model = ...

     //manually invoke the model binding process considering only query string data
     //The custom model binder will be used only if it was globally registered
     //in the binders dictionary or set in an attribute of the model class
     TryUpdateModel(model, new QueryStringValueProvider())

     ...
}
_

インターフェイスIModelBinderProviderを実装し、次のようにglobal.asaxに登録することで、モデルバインダーを選択するための独自のロジックを実装するオプションもあります。

_ModelBinderProviders.BinderProviders.Add(new CustomModelBinderProvider()) 
_

メソッドパラメーターで属性を使用する1つの方法は、その特定のメソッドに対して、他の方法で使用されるモデルバインダーをオーバーライドすることです。したがって、クラスのモデルバインダーをグローバルに登録し、属性を使用して1つの特定のアクションメソッドでオーバーライドできます。

結局、モデルバインダーを選択するためのかなりの数のオプションがあります。 asp MVC 3では、これは次の方法で解決されます(デフォルトのControllerActionInvokerを使用していると仮定)

  1. アクションのパラメーターの属性。 ControllerActionInvokerクラス のGetParameterValueメソッドを参照してください

  2. IModelBinderProviderから返されたバインダー。 ModelBinderDictionaryクラス のGetBinderメソッドを参照してください

  3. ModelBinders.Bindersディクショナリにグローバルに登録されているバインダー。

  4. モデルタイプの[ModelBinder()]属性で定義されたバインダー。

  5. DefaultModelBinder。

32
Daniel J.G.

Global.asaxのモデルバインダーコレクションに追加するのではなく属性を使用する利点は、バインダーを特定のタイプに関連付けるのではなく、使用する特定のバインダーをメソッド(またはクラス)に指示できることです。次に、タイプではなくコンテキストに基づいてモデルを作成できます。

1
user3667333