私はこれに似た質問をたくさん見てきましたが、私がすでに持っている以上の答えを持っているものはないようです.
特定のストック UI コントロールを表すいくつかの複雑な型を含み、いくつかの検証ロジックが添付されている ViewModel があります。これらを EditorTemplate/DisplayTemplate に基づいてページにレンダリングする必要があり、開発者がコントローラー内でビューモデルを使用できるように、フォームの送信時に適切にバインドするプロパティも必要です。
これの簡単な例は
public class TestViewModel
{
public HierarchyField MyField {get; set; }
}
最も簡単な方法として、開発者がこのビュー モデルのエディターを簡単な方法で作成できるようにする必要があります。
@Html.EditorForModel()
HierarchyField の編集可能な部分については、そのタイプのカスタム EditorTemplate 内にフィールドを設定します。
カスタム MetaDataProvider を使用し、IsComplexType をオーバーライドすることで、これをレンダリングできるようになりました。これは、完全に快適ではありませんが、仕事をします。そのソリューションの詳細はこちら ( http://blogs.msdn.com/b/stuartleeks/archive/2010/04/01/collections-and-asp-net-mvc-templated-helpers-part-3.aspx?Redirected =真)
フォームの送信時にモデル バインディングを取得してプロパティを更新し、HierarchyField クラスのメソッドを呼び出してカスタム検証を少し実行し、その呼び出しの結果に基づいて ModelState を更新しようとしています。
最初に、BindProperty オーバーライド内にロジックを持つ DefaultModelBinder のサブクラスを作成し、バインドされているプロパティがこの型であるかどうかを確認しました。これまでのところすべて順調です。問題は、意図した値を取り、その値の検証を試みるインスタンス メソッドを呼び出したいときに発生します。BindProperty メソッドは、プロパティに関するメタデータを検索できる PropertyDescriptor のインスタンスと、値を読み取ることができる ValueProvider を持つ BindingContext を提供しますが、次の複合型のインスタンスは返されません。
bindingContext.ValueProvider.GetValue(propertyDescriptor.Name + ".Value")
propertyDescriptor.Name + ".Value" は、私の EditorTemplate に次のものがあるという事実に相当します。
@Html.TextBoxFor(model => model.Value)
タイプの代わりに、返されたフィールドの Value プロパティへの参照しか取得していないため、String[] を取得します。これを機能させるには、HierarchyField に何らかの ValueProvider を登録する必要があると想定していますが、セットアップするこれらのタイプがいくつかあるため、理想的にはもう少し一般的なものを探しています。そのサブクラスは共通の抽象型です (これらはすべて、値の文字列表現を返す「Value」というプロパティを持っています)。
正直なところ、このプロセス全体が非常に苦痛に思えて、これを行うための本当に簡単なことを見逃しているように感じます。残念ながら、これらのフィールドが多数あるため、これを汎用にする必要があります。このモデル、またはフィールドが検証を処理するための同様のものが必要です。これの多くは、DataAnnotation 検証属性では実行できないためです。特定のビュー モデルに関連付けられたカスタム コードを作成することはできず、特定のフィールドに関連付けられたコードを最小限に抑え、基本クラス (FieldBase) とそのサブクラスに適用されるコードを優先したいと考えています。
誰かがそれを見る必要がある場合は、追加のコードを投稿してください。