View Models がすべて継承する BaseViewModel があります。
public class MagazineViewModel : BaseOutputViewMode
{
public string TitleOfPublication { get; set; }
}
私のコントローラーでは、ファクトリ メソッドを使用して、入力に基づいて正しいビュー モデルを返します。
// e.g. viewModel contains an instance of MagazineViewModel
BaseOutputViewModel viewModel = BaseOutputViewModel.GetOutputViewModel(output);
TryUpdateModel を使用して、「TitleOfPublication」キーが含まれていることがわかっている FormCollection にバインドしようとすると、ビュー モデルに設定されません。
if (!TryUpdateModel(viewModel, form))
これは、BaseOutputViewModel を使用して FormCollection キーをバインドする DefaultModelBinder と関係があると思います。「TitleOfPublication」は含まれていませんが、派生 MagazineViewModel には含まれています。
DefaultModelBinder の BindModel 動作をオーバーライドするために、独自のモデル バインダーを作成しようとしています。すべて正しく配線されており、TryUpdateModel 呼び出しの直後にデバッグできます。
public class TestModelBinder : DefaultModelBinder, IFilteredModelBinder
{
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
// Tried the following without success ....
// 1. Quick hardcoded test
// bindingContext.ModelType = typeof(MagazineViewModel);
// 2. Set ModelMetadata, hardcoded test again
// bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(null, typeof(MagazineViewModel));
// 3. Replace the entire context
// ModelBindingContext context2 = new ModelBindingContext();
// context2.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(null, typeof(MagazineViewModel));
// context2.ModelName = bindingContext.ModelName;
// context2.ModelState = bindingContext.ModelState;
// context2.ValueProvider = bindingContext.ValueProvider;
// bindingContext = context2;
}
}
しかし、bindingContext の操作方法がわかりません。派生したビュー モデル プロパティを使用してバインドするように DefaultModelBinder に指示できるようにするには、何を更新する必要がありますか? それとも、私はこれを完全に誤解していますか!
MvcContrib の DerivedTypeModelBinder と同じように、CreateModel をオーバーライドしようとしましたが、バインダーに操作するモデルのインスタンスを与えているため、CreateModel が呼び出されることはありません。Mvc DLL で Reflector を使用すると、モデルが null の場合にのみ CreateModel を呼び出す "BindComplexModel" が存在します。
if (model == null)
{
model = this.CreateModel(controllerContext, bindingContext, modelType);
}
どんなポインタでも大歓迎です!
乾杯