Modèle de liaison personnalisé héritant de DefaultModelBinder

Je suis tenter de construire un modèle de liaison personnalisé pour MVC 4, qui va hériter de DefaultModelBinder. J'aimerais qu'il intercepter toutes les interfaces à tout de liaison de niveau et tenter de charger le type désiré à partir d'un champ caché appelé AssemblyQualifiedName.

Voici ce que j'ai à ce jour (simplifié):

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);
    }
}

Exemple Créer.cshtml fichier (simplifié):

@model Models.ScheduledJob

@* Begin Form *@
@Html.Hidden("AssemblyQualifiedName", Model.Job.GetType().AssemblyQualifiedName)

@Html.Partial("_JobParameters")
@* End Form *@

Ci-dessus partielle _JobParameters.cshtml regarde le Model.Job's propriétés et renforce les contrôles d'édition, semblable à @Html.EditorFor(), mais avec un certain balisage. Le ScheduledJob.Job de la propriété est de type IJob (interface).

Exemple ScheduledJobsController.cs (simplifié):

[HttpPost]
public ActionResult Create(ScheduledJob scheduledJob)
{
    //scheduledJob.Job here is not null, but has only default values
}

Quand j'ai enregistrer le formulaire, il interprète le type d'objet correctement et obtient une nouvelle instance, mais les propriétés de l'objet ne sont pas fixés à leurs valeurs appropriées.

De quoi dois-je faire pour dire le classeur par défaut pour prendre en charge le site de liaison du type spécifié?

OriginalL'auteur Albert Bori | 2013-05-25