【问题标题】:Custom model binder not firing up for web api 2自定义模型绑定器未针对 web api 2 启动
【发布时间】:2015-08-27 21:41:03
【问题描述】:

所以现有的问题都没有回答这个问题。

我已经为 web api 2 实现了一个自定义模型绑定器,如下所示

    public class AModelBinderProvider : IModelBinderProvider
{
    public IModelBinder GetBinder(Type modelType)
    {
        return modelType == typeof(A) ? new AdAccountModelBinder() : null;
    }
}

public class AModelBinder : DefaultModelBinder
{
    private readonly string _typeNameKey;

    public AModelBinder(string typeNameKey = null)
    {
        _typeNameKey = typeNameKey ?? "type";
    }

    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var providerResult = bindingContext.ValueProvider.GetValue(_typeNameKey);

        if (providerResult != null)
        {
            var modelTypeName = providerResult.AttemptedValue;

            SomeEnum type;

            if (!Enum.TryParse(modelTypeName, out type))
            {
                throw new InvalidOperationException("Bad Type. Does not inherit from AdAccount");
            }

            Type modelType;

            switch (type)
            {
                case SomeEnum.TypeB:
                    modelType = typeof (B);
                    break;
                default:
                    throw new InvalidOperationException("Bad type.");
            }

            var metaData =
                ModelMetadataProviders.Current
                                      .GetMetadataForType(null, modelType);

            bindingContext.ModelMetadata = metaData;
        }

        // Fall back to default model binding behavior
        return base.BindModel(controllerContext, bindingContext);
    }

模型定义如下 -

Public class A {}
Public Class B : A {}

Web Api Action 如下 -

        [System.Web.Http.HttpPost]
    [System.Web.Http.Route("api/a")]
    [System.Web.Http.Authorize]
    public async Task<HttpResponseMessage> Add([ModelBinder(typeof(AModelBinderProvider))]Models.A a)
{}

在 Application_Start 中将我的提供者注册为绅士 -

            var provider = new AdAccountModelBinderProvider();
        ModelBinderProviders.BinderProviders.Add(provider);

我的自定义 Binder 仍然拒绝启动。

我迷路了。我错过了什么?

【问题讨论】:

  • 什么是AdAccountModelBinder?你实现了AModelBinder

标签: c# .net asp.net-mvc asp.net-web-api model-binding


【解决方案1】:

你需要实现IModelBinder接口:

看下面自定义的例子:

public class MyModelBinder : IModelBinder
{
    public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
    {
        try
        {
            bindingContext.Model = new TestClass();

            //following lines invoke default validation on model
            bindingContext.ValidationNode.ValidateAllProperties = true;
            bindingContext.ValidationNode.Validate(actionContext);

            return true;
        }
        catch
        {
            return false;
        }
    }
}
  • 设置模型绑定器

有几种方法可以设置模型绑定器。首先,您可以在参数中添加一个 [ModelBinder] 属性。

public HttpResponseMessage Get([ModelBinder(typeof(MyModelBinder))] TestClass objTest)

您还可以为类型添加 [ModelBinder] 属性。 Web API 将为该类型的所有参数使用指定的模型绑定器。

[ModelBinder(typeof(MyModelBinder))]
public class TestClass
{
    // ....
}

最后,您可以将模型绑定器提供程序添加到 HttpConfiguration。模型绑定器提供者只是一个创建模型绑定器的工厂类。您可以通过从 ModelBinderProvider 类派生来创建提供程序。但是,如果您的模型绑定器处理单一类型,则使用专为此目的设计的内置 SimpleModelBinderProvider 会更容易。以下代码显示了如何执行此操作。

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        var provider = new SimpleModelBinderProvider(
            typeof(TestClass), new MyModelBinder());
        config.Services.Insert(typeof(ModelBinderProvider), 0, provider);

        // ...
    }
}

使用模型绑定提供程序,您仍然需要将 [ModelBinder] 属性添加到参数中,以告诉 Web API 它应该使用模型绑定器而不是媒体类型格式化程序。但是现在你不需要在属性中指定模型绑定器的类型了:

public HttpResponseMessage Get([ModelBinder] TestClass objTestClass) { ... }

【讨论】:

    【解决方案2】:

    我认为,您应该使用命名空间 System.Web.ModelBinding 中的 DefaultModelBinder / 命名空间 System.Web.Http.ModelBinder 中的 IModelBinder。 我也认为你做了一些不必要的想法,比如在 Application_Start 中注册提供者,因为你正在使用 ModelBinder 指令。

    更多详情请看http://blog.learningtree.com/creating-a-custom-web-api-model-binder/

    【讨论】:

      【解决方案3】:

      可能需要在 WebApiConfig 中添加自定义参数绑定规则?

      config.ParameterBindingRules.Insert(0, GetCustomParameterBinding);
      

      在此处查看示例:How to pass ObjectId from MongoDB in MVC.net

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-09-04
        • 1970-01-01
        • 1970-01-01
        • 2013-07-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多