DefaultModelBinder
から継承するMVC 4のカスタムモデルバインダーを作成しようとしています。 のインターフェイスを傍受してのバインディングレベルを取得し、AssemblyQualifiedName
という非表示のフィールドから目的のタイプをロードしようとします。DefaultModelBinderから継承したカスタムモデルバインダー
ここで私は今のところ(簡体字)しているものです:
public class MyWebApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
ModelBinders.Binders.DefaultBinder = new InterfaceModelBinder();
}
}
public class InterfaceModelBinder : DefaultModelBinder
{
public override object BindModel(ControllerContext controllerContext,
ModelBindingContext bindingContext)
{
if (bindingContext.ModelType.IsInterface
&& controllerContext.RequestContext.HttpContext.Request.Form.AllKeys.Contains("AssemblyQualifiedName"))
{
ModelBindingContext context = new ModelBindingContext(bindingContext);
var item = Activator.CreateInstance(
Type.GetType(controllerContext.RequestContext.HttpContext.Request.Form["AssemblyQualifiedName"]));
Func<object> modelAccessor =() => item;
context.ModelMetadata = new ModelMetadata(new DataAnnotationsModelMetadataProvider(),
bindingContext.ModelMetadata.ContainerType, modelAccessor, item.GetType(), bindingContext.ModelName);
return base.BindModel(controllerContext, context);
}
return base.BindModel(controllerContext, bindingContext);
}
}
例Create.cshtml(簡体)ファイル:
@model Models.ScheduledJob
@* Begin Form *@
@Html.Hidden("AssemblyQualifiedName", Model.Job.GetType().AssemblyQualifiedName)
@Html.Partial("_JobParameters")
@* End Form *@
を_JobParameters.cshtml
上記部分がModel.Job
のプロパティを見て、ビルドします編集コントロールは@Html.EditorFor()
に似ていますが、余分なマークアップがあります。 ScheduledJob.Job
プロパティのタイプはIJob
(インターフェイス)です。
例ScheduledJobsController.cs(簡体字):私は、フォームを保存するとき
[HttpPost]
public ActionResult Create(ScheduledJob scheduledJob)
{
//scheduledJob.Job here is not null, but has only default values
}
、それは正しくオブジェクト型を解釈し、新しいインスタンスを取得しますが、オブジェクトのプロパティは、その適切に設定されていません値。
これ以外に、指定したタイプのプロパティーバインドを引き継ぐためにデフォルトのバインダーに指示する必要がありますか?
上記のバインダーはどこに追加しましたか?私はバインダーModelBinders.Binders.Add(typeof(Organization)、新しいOrganizationModelBinder(DependencyResolver.Current.GetService()))を持っています。 app_start()メソッドのglobal.asax.csページにあります。私はルートとバンドルの仕方のようなモデルバインダーを登録するためのより良い方法を探していますか? –
mmssaann
@mmssaann私はglobal.asax.csの 'Application_Start()'に 'ModelBinders.Binders.DefaultBinder = new MyCustomModelBinder();'を使用しました。次に、私はModelBinderを抽象クラスやインタフェースを扱えるように十分に汎用化し、そうでない場合はバインディングロジックをDefaultModelBinderに渡しました。 –