Я пытаюсь создать собственное связующее устройство для MVC 4, которое наследует от DefaultModelBinder
. Я бы хотел, чтобы он перехватывал любые интерфейсы на любом уровне привязки и пытался загрузить желаемый тип из скрытого поля под названием 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
}
Когда я сохраняю форму, она правильно интерпретирует тип объекта и получает новый экземпляр, но свойства объекта не устанавливаются в соответствующие значения.
Что еще мне нужно сделать, чтобы сообщить связующему по умолчанию взять на себя привязку свойства указанного типа?