【问题标题】:How do I create a custom model binder using the `BindModel(HttpActionContext actionContext...` signature?如何使用 `BindModel(HttpActionContext actionContext...` 签名创建自定义模型绑定器?
【发布时间】:2012-04-12 05:06:12
【问题描述】:

我需要知道如何在 MVC 4 中创建自定义 IModelBinder,它已被更改。

必须实现的新方法是:

bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext);

【问题讨论】:

    标签: asp.net-mvc asp.net-mvc-4 asp.net-web-api imodelbinder


    【解决方案1】:

    IModelBinder 接口有 2 个:

    1. System.Web.Mvc.IModelBinder 和之前的版本一样,没有变化
    2. System.Web.Http.ModelBinding.IModelBinder 由 Web API 和 ApiController 使用。所以基本上在这个方法中,你必须将actionContext.ActionArguments 设置为相应的值。您不再返回模型实例。

    【讨论】:

    • 还必须注册一个自定义模型绑定器。 ASP.Net Web API 的方式与 MVC3 不同。查看 this post 以了解如何在 MVC4 Beta 中执行此操作。答案的底部很难弄清楚,但请注意,您将其设置为 global.asax.csGlobalConfiguration.Configuration.ServiceResolver.GetServices...
    【解决方案2】:

    This link,由 Steve 提供,提供了完整的答案。我在这里添加它以供参考。归功于 asp.net 论坛上的 dravva。

    首先,创建一个派生自IModelBinder 的类。正如 Darin 所说,一定要使用 System.Web.Http.ModelBinding 命名空间,而不是熟悉的 MVC 等效名称。

    public class CustomModelBinder : IModelBinder
    {
        public CustomModelBinder()
        {
            //Console.WriteLine("In CustomModelBinder ctr");
        }
    
        public bool BindModel(
            HttpActionContext actionContext, 
            ModelBindingContext bindingContext)
        {
            //Console.WriteLine("In BindModel");
            bindingContext.Model = new User() { Id = 2, Name = "foo" };
            return true;
        }
    }
    

    接下来,提供一个提供程序,它充当您的新活页夹以及您将来可能添加的任何其他活页夹的工厂。

    public class CustomModelBinderProvider : ModelBinderProvider
    {
        CustomModelBinder cmb = new CustomModelBinder();
        public CustomModelBinderProvider()
        {
            //Console.WriteLine("In CustomModelBinderProvider ctr");
        }
    
        public override IModelBinder GetBinder(
            HttpActionContext actionContext,
            ModelBindingContext bindingContext)
        {
            if (bindingContext.ModelType == typeof(User))
            {
                return cmb;
            }
    
            return null;
        }
    }
    

    最后,在 Global.asax.cs 中包含以下内容(例如 Application_Start)。

    var configuration = GlobalConfiguration.Configuration;
    
    IEnumerable<object> modelBinderProviderServices = configuration.ServiceResolver.GetServices(typeof(ModelBinderProvider));
    List<Object> services = new List<object>(modelBinderProviderServices);
    services.Add(new CustomModelBinderProvider());
    configuration.ServiceResolver.SetServices(typeof(ModelBinderProvider), services.ToArray());
    

    现在,您可以将新类型作为参数传递给您的操作方法。

    public HttpResponseMessage<Contact> Get([ModelBinder(typeof(CustomModelBinderProvider))] User user)
    

    甚至

    public HttpResponseMessage<Contact> Get(User user)
    

    【讨论】:

    • 我相信,只要您在操作中明确使用 [ModelBinder(typeof(CustomModelBinderProvider))],就不需要 ModelBinderProvider。
    【解决方案3】:

    Todd 帖子的 RC 更新:

    已简化添加模型绑定器提供程序:

    var configuration = GlobalConfiguration.Configuration;
    
    configuration.Services.Add(typeof(ModelBinderProvider), new YourModelBinderProvider());
    

    【讨论】:

    • 这对我有用。有没有办法在全局范围内执行此操作,即设置默认模型绑定器?
    【解决方案4】:

    在没有 ModelBinderProvider 的情况下添加模型绑定器的一种更简单的方法是:

    GlobalConfiguration.Configuration.BindParameter(typeof(User), new CustomModelBinder());
    

    【讨论】:

    • 这很完美!无论出于何种原因,我无法让此页面上的任何其他示例与 MVC4 一起使用。 ModelBinderProvider 的接口似乎已经改变。但是删除 ModelBinderProvider 并将此代码添加到 Application_Start 效果很好!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-31
    • 1970-01-01
    • 1970-01-01
    • 2013-07-31
    • 2021-09-30
    • 1970-01-01
    • 2018-08-22
    相关资源
    最近更新 更多