私は ASP.NET MVC3 を使用していますが、デフォルトのモデルバインダーがパブリック プロパティにバインドされているが、パブリック フィールドにはバインドされていないことに疑問を抱いています。
通常、モデル クラスをプロパティで定義するだけですが、いくつかのフィールドを含む定義済みのクラスを使用することもあります。そして毎回、モデルバインダーはフィールドが好きではないことをデバッグして覚えておく必要があります。
質問: その背後にある理由は何ですか?
私は ASP.NET MVC3 を使用していますが、デフォルトのモデルバインダーがパブリック プロパティにバインドされているが、パブリック フィールドにはバインドされていないことに疑問を抱いています。
通常、モデル クラスをプロパティで定義するだけですが、いくつかのフィールドを含む定義済みのクラスを使用することもあります。そして毎回、モデルバインダーはフィールドが好きではないことをデバッグして覚えておく必要があります。
質問: その背後にある理由は何ですか?
しかし、いくつかのフィールドを含む定義済みのクラスを使用することがあります
デフォルトのモデルバインダーがプロパティでのみ機能する正確な理由についての質問にはお答えできませんが(私の推測では、この方法でより良いカプセル化を尊重し、フィールドが表すオブジェクトの内部状態の変更を回避します)事前定義されたクラスの呼び出しは、通常、ビュー モデルである必要があります。コントローラー アクションとの間で常にビュー モデルを使用する必要があります。これらのビュー モデルは、特定のビューの要件を満たすために特別に定義されたクラスです。
要点に戻ります。フィールドは、指定されたクラス内からのみ変更する必要があります。外部から直接アクセスしないでください。クラスの内部状態を表し、保持します。一方、プロパティは、外部の世界に公開する必要があるものです。プロパティの getter/setter にカスタム ロジックがあるとします。フィールドを直接変更すると、このカスタム ロジックが壊れ、オブジェクトが矛盾した状態になる可能性があります。
フィールドを無視する理由は、バインダーのパフォーマンスを向上させるためかもしれません。すべてのフィールドとプロパティを検索する代わりに。モデル バインダーは、プロパティのみを検索します。
モデルバインダーはキャッシュを使用してパフォーマンスを向上させていると思いますが。
DefaultModelBinder は、パブリック メソッド DefaultModelBinder.BindModelと、オーバーライドに使用できるいくつかの保護されたメソッドを公開します。それらはすべてここにリストされています。
モデルに加えて、これらのメソッドはプロパティのみを参照し、フィールドは参照しません。
whereXYZ
はいずれModel,
かProperty/ies,
または両方を表します。
ご覧のFields
とおり、これらの名前はまったく言及されていません。ダリンが説明したように、モデルの状態への直接的な変更はバインダーによって許容されません。したがってField
、その方法ではありません。
また、もう 1 つの重要なクラスであるModelBindingContextを確認することもできます。このクラスのインスタンスは に渡され、BindModel,
続いてモデル タイプBindSimpleModel,
にBindComplexModel,
応じて渡されます ( string, int,
... は単純と見なされ、それ以外はすべて複雑です)。
したがって、このコンテキストには次のプロパティがあります。
つまり、これらのクラスをオーバーライドして特別なアクションを実行しない限り、ViewModel 内のフィールドを参照する手段がありません。
ただし、フレームワークとの戦いには注意してください。代わりに、フレームワークに従う方が常に簡単です。
編集: ModelMetadataクラスは、モデルをバインドするために必要なすべてのデータを保持します。ただし、そのコードには、フィールドやフィールド名などの兆候はありません。プロパティのみが参照およびアクセスされます。そのため、 DefaultModelBinderとModelBinderContextを継承してオーバーライドしようとしても、フィールドにアクセスすることはできません。アクセス修飾子がパブリック、プライベートなどであることを気にする必要はありません。
これで大部分が説明されることを願っています。