【发布时间】:2013-05-20 18:49:00
【问题描述】:
我正在尝试为 MVC 4 构建一个自定义模型绑定器,它将继承自 DefaultModelBinder。我希望它在 any 绑定级别拦截任何接口,并尝试从名为 AssemblyQualifiedName 的隐藏字段加载所需的类型。
这是我到目前为止的内容(简化):
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
}
当我保存表单时,它会正确解释对象类型并获取一个新实例,但对象的属性没有设置为适当的值。
我还需要做什么来告诉默认绑定器接管指定类型的属性绑定?
【问题讨论】:
标签: c# asp.net-mvc-4 model-binding