Próbuję utworzyć niestandardowy segregator modelu dla MVC 4, który będzie dziedziczyć po DefaultModelBinder
. Chciałbym, aby przechwytywał on wszelkie interfejsy na poziomie powiązaniai próbował załadować żądany typ z ukrytego pola o nazwie AssemblyQualifiedName
.Spojrzenie na model niestandardowy dziedziczące z obiektu DefaultModelBinder
Oto co mam do tej pory (uproszczony):
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);
}
}
plik
Przykład Create.cshtml (uproszczony):
@model Models.ScheduledJob
@* Begin Form *@
@Html.Hidden("AssemblyQualifiedName", Model.Job.GetType().AssemblyQualifiedName)
@Html.Partial("_JobParameters")
@* End Form *@
Powyższy częściowy _JobParameters.cshtml
patrzy na właściwościom Model.Job
„s i buduje formanty edycji, podobne do @Html.EditorFor()
, ale z dodatkowymi znacznikami. Właściwość ScheduledJob.Job
jest typu IJob
(interfejs).
Przykład ScheduledJobsController.cs (-i)
[HttpPost]
public ActionResult Create(ScheduledJob scheduledJob)
{
//scheduledJob.Job here is not null, but has only default values
}
Kiedy zachować formę, interpretuje typ obiektu prawidłowo i pobiera nową instancję, ale właściwości obiektu nie są ustawione na właściwe wartości.
Co jeszcze muszę zrobić, aby powiadomić domyślny spinacz o przejęciu powiązania właściwości określonego typu?
Skąd dodałeś powyższy segregator? Mam binder ModelBinders.Binders.Add (typeof (Organization), new OrganizationModelBinder (DependencyResolver.Current.GetService())); na stronie global.asax.cs w metodzie App_start(). Poszukuję tylko lepszych sposobów rejestrowania segregatorów modeli, takich jak sposób trasowania i pakowania? –
mmssaann
@mmssaann Użyłem 'ModelBinders.Binders.DefaultBinder = new MyCustomModelBinder();' w global.asax.cs 'Application_Start()'. Następnie zrobiłem mój Generator ModelBinder wystarczająco ogólny, aby obsłużyć dowolną klasę abstrakcyjną lub interfejs, w przeciwnym razie przekazać logikę wiązania do DefaultModelBinder. –