Ich versuche, ein benutzerdefiniertes Modellbinder für MVC 4 zu erstellen, das von DefaultModelBinder
erben wird. Ich möchte, dass es Schnittstellen unter Binding-Ebene abfangen und versuchen, den gewünschten Typ aus einem versteckten Feld namens AssemblyQualifiedName
laden.Benutzerdefiniertes Modellbinder, der von DefaultModelBinder erbt
Hier ist, was ich bisher haben (vereinfacht):
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);
}
}
Beispiel Create.cshtml Datei (vereinfacht):
@model Models.ScheduledJob
@* Begin Form *@
@Html.Hidden("AssemblyQualifiedName", Model.Job.GetType().AssemblyQualifiedName)
@Html.Partial("_JobParameters")
@* End Form *@
Die obige Teil _JobParameters.cshtml
schaut auf die Model.Job
‚s Eigenschaften und baut die Bearbeitungssteuerelemente, ähnlich wie @Html.EditorFor()
, aber mit etwas extra Markup. Die ScheduledJob.Job
Eigenschaft ist vom Typ IJob
(Schnittstelle).
Beispiel ScheduledJobsController.cs (vereinfacht):
[HttpPost]
public ActionResult Create(ScheduledJob scheduledJob)
{
//scheduledJob.Job here is not null, but has only default values
}
Wenn ich die Form speichern, interpretiert er den Objekttyp korrekt und bekommt eine neue Instanz, aber die Eigenschaften des Objekts sind nicht auf ihre entsprechenden eingestellt wird Werte.
Was muss ich sonst tun, um dem Standardordner mitzuteilen, dass er die Eigenschaftsbindung des angegebenen Typs übernehmen soll?
Wo haben Sie den obigen Binder hinzugefügt? Ich habe Binder ModelBinders.Binders.Add (typeof (Organization), neuer OrganizationModelBinder (DependencyResolver.Current.GetService())); auf der Seite global.asax.cs in der App_start() -Methode. Ich bin nur auf der Suche nach besseren Möglichkeiten, um die Modellbinder zu registrieren, wie wir routen und bündeln? –
mmssaann
@mmssaann Ich habe 'ModelBinders.Binders.DefaultBinder = new MyCustomModelBinder(); 'in global.asax.cs' Application_Start() 'verwendet. Dann habe ich meinen ModelBinder generisch genug gemacht, um mit jeder abstrakten Klasse oder Schnittstelle umgehen zu können, ansonsten überlasse ich die Bindungslogik dem DefaultModelBinder. –