ASP.NET MVC ModelBindingContextクラス - モデル値はどのように人口がかかっていますか?

StackOverflow https://stackoverflow.com/questions/3523752

質問

Model BindersがASP.NET MVCでどのように作業を行っているかについて、私は頭を少しひっかいています。

具体的には、bindModel()メソッドには、モデル名とタイプを保持するモデルバインディングコンターテキストパラメーターがありますが、ModelBindingContextがこれらの値をどのように受信するかはわかりません。

MVCモデルは、投稿されたフォーム値またはクエリ文字列パラメーター、またはその他のデータソースから入力する必要があります。しかし、モデルBindingContextに渡されたモデルタイプを決定するメカニズムは、個々の投稿値を含む単純なリストで、別のモデルタイプで選択された1つのモデルタイプはどのように選択されますか?

ModelBindingContextが渡されているモデルのタイプを「知っている」ように見えますが、それがどこから来たのか、それを住むことに関係するワークフローがわかりません。

役に立ちましたか?

解決

興味深い質問。 MVCが行うことの簡単な概要を次に示します。それはすべて、ControlleractionInovkerクラスによって処理されます。これは特定の順序ではありませんが、近いです。

  1. ControllerActionInovkerは、反射を介してパラメータータイプを決定します。
  2. 次のValueProvidersは、HTTPContextリクエストフォーム、ルート、クエリストリングなどから作成されます。プロパティ。独自の価値プロバイダーを提供することもできます。
  3. これらのvalueProvidersは、仮想ValueProviderとして機能するコレクションを介してモデルバインディングコンテキストに提供されます。
  4. 次に、ControllerActionInovkerは、特定のタイプのModelBinderを探します。見つけられない場合は、デフォルトの内蔵DefaultModelbinderにデフォルトです。
  5. ほとんどの場合、DefaultModelbinderが使用されます。それは、モデルを作成し、ValueProvidersを使用して、キーとしてモデルプロパティ名を使用してプロパティを値に接続することです。 ValueProvidersに値がある場合、タイプ変換を担当するValueProviderResultオブジェクトを返します。

あなたはあなた自身のためにこれを見ることができます codeplex.comにあるASP.NET MVCソース. 。 controlleractioninvokerクラスとgetParametervalueメソッドを探してください。

他のヒント

ModelBindingContextは、次のいずれかが必要なため、渡されているモデルのタイプを「知っています」

  • モデルにModelBinder属性を追加します
  • modelbinders.binders.add()メソッドを使用して、モデルをモデルに登録します。

ModelBinder属性の例:

[ModelBinder(typeof(ContactBinder))]
public class Contact { ... }

modelbinders.binders.add()の例:

void Application_Start()
{
  ModelBinders.Binders[typeof(Contact)] = new ContactBinder();
}

ModelBinderを登録し、BindModelメソッドを実装した場合:

public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { ... }
  1. Query ModelBindingContext.ModelTypeは、モデルと等しくなります

    if (bindingContext.ModelType == typeof(Contact)) { ... }
    
  2. ModelBindingContext.ValueProviderプロパティからモデルを再水Drateして、フォーム投稿、ルートデータ、クエリ文字列のデータを表すデータを表すValueProviderResultインスタンスを取得

    bindingContext.ValueProvider["Name"].AttemptedValue;
    

次の本が使用されましたASP.NET MVC 2アクションASP.NET MVC 1.0をすばやく

私が見る方法は、controllerActionInvokerが反射を使用してパラメータータイプを取得することです。その後、モデルバインダーがそのタイプに対処するように割り当てられているかどうかをチェックします。もしそうなら、このモデルバインダーをインスタンス化して、(モデルオブジェクト、モデルを含むバインディングコンテキストを渡すことです。そのパラメータータイプオブジェクトの名前、モデルタイプ、プロパティフィルター)および他のすべてのバリュープロバイダー(フォーム、クエリ文字列など)のバリュープロバイダーコレクション(ModelBindingContext.ValueProvider)、1つの大きな仮想値プロバイダーとして機能します。

その後、ModelBinder自体はリフレクションを使用して、バインドするように割り当てられたタイプのすべてのプロパティ名を取得し、すべてのバリュープロバイダー(ModelBindingContext.ValueProvider)に対して再帰的に実行し、それらの価値プロバイダーのプロパティ名を探し、それらの値を拘束する値を拘束します。名前(クライアントから取られた)は、ValueプロバイダーがValueProviderResultオブジェクトを返すときにタイププロパティ名と一致し、モデル上のそれぞれのプロパティの名前と値が付いています。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top