自定义模型绑定从DefaultModelBinder继承 [英] Custom Model Binder inheriting from DefaultModelBinder

查看:728
本文介绍了自定义模型绑定从DefaultModelBinder继承的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图建立MVC 4自定义模型绑定将从 DefaultModelBinder 继承。我想它在拦截任何接口的任何的结合水平,并试图从名为 AssemblyQualifiedName 一个隐藏字段加载所需的类型。

I'm attempting to build a custom model binder for MVC 4 that will inherit from DefaultModelBinder. I'd like it to intercept any interfaces at any binding level and attempt to load the desired type from a hidden field called AssemblyQualifiedName.

下面是我到目前为止(简体):

Here's what I have so far (simplified):

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文件(简体):

Example Create.cshtml file (simplified):

@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 (接口)。

The above partial _JobParameters.cshtml looks at the Model.Job's properties and builds the edit controls, similar to @Html.EditorFor(), but with some extra markup. The ScheduledJob.Job property is of type IJob (interface).

例ScheduledJobsController.cs(简体):

Example ScheduledJobsController.cs (simplified):

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

当我保存的形式,它除$ P $点对象的类型正确,并得到一个新的实例,但对象的属性不被设置为它们的相应的值。

When I save the form, it interprets the object type correctly and gets a new instance, but the properties of the object are not being set to their appropriate values.

还有什么我需要做的这告诉默认联接管财产指定类型的绑定?

What else do I need to do to this to tell the default binder to take over the property binding of the specified type?

推荐答案

<一个href=\"http://ivonna.biz/blog/2012/2/2/custom-aspnet-model-binders-series,-part-3-subclassing-your-models.aspx\">This文章给我看,我是模型绑定过于复杂。下面code工作:

This article showed me that I was over-complicating the model binder. The following code works:

public class InterfaceModelBinder : DefaultModelBinder
{
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        if (bindingContext.ModelType.IsInterface)
        {
            Type desiredType = Type.GetType(
                EncryptionService.Decrypt(
                    (string)bindingContext.ValueProvider.GetValue("AssemblyQualifiedName").ConvertTo(typeof(string))));
            bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(null, desiredType);
        }

        return base.BindModel(controllerContext, bindingContext);
    }
}

这篇关于自定义模型绑定从DefaultModelBinder继承的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆