Swagger没有调用WebAPI Custom ModelBinder

时间:2016-06-08 09:05:47

标签: c# asp.net-web-api2 swagger

目标:我正在设计一个REST API,允许用户在查询字符串上传递HTTP GET请求的参数。像

这样的东西

http://fake.api.com/search?param1=123&param2=car&pageSize=10

实现:在服务器端,我有一个自定义模型绑定器,它从请求查询字符串中获取参数并将它们转换为C#对象,这样我的控制器操作方法就不必解析查询字符串。 所以控制器动作方法签名看起来像

public async Task<HttpResponseMessage> Get([ModelBinder]RequestObject request)

当我从Fiddler测试api并传递查询字符串值时,自定义模型绑定器工作,我在控制器操作中获得了具有正确值的c#对象。

但是当我使用Swagger进行测试时,不会调用modelbinder并且action参数中的值为null。模型参数单独显示,而不是显示模型。

我该如何解决这个问题?

我的自定义模型绑定器:

   public class RequestObjectModelBinder : IModelBinder
    {
        public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
        {
            if (bindingContext.ModelType != typeof(RequestObject))
            {
                return false;
            }

            var searchCriteria = new RequestObject();
            var type = searchCriteria.GetType();

            var querystringVals = actionContext.Request.GetQueryNameValuePairs();
            var keyValuePairs = querystringVals as IList<KeyValuePair<string, string>> ?? querystringVals.ToList();
            if (!keyValuePairs.Any())
            {
                bindingContext.Model = searchCriteria;
                return true;
            }

            foreach (var value in keyValuePairs)
            {
                var key = value.Key;
                var prop = type.GetProperty(key, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);
                if (prop == null)
                {
                    continue;
                }

                prop.SetValue(searchCriteria, Convert.ChangeType(value.Value,prop.PropertyType), null);
            }

            var validationResults = new Collection<ValidationResult>();
            var isValid = Validator.TryValidateObject(searchCriteria, new ValidationContext(searchCriteria, null, null), validationResults, true);
            if (!isValid)
            {
                foreach (var result in validationResults)
                {
                    bindingContext.ModelState.AddModelError("", result.ErrorMessage);
                }
            }

            bindingContext.Model = searchCriteria;

            return true;
        }

2 个答案:

答案 0 :(得分:0)

[HttpGet]
public async Task<HttpResponseMessage> Get([FromUri]RequestObject request)

给定RequestObject的工作是否具有以下签名:

public class RequestObject
{
    public string param1 { get; set; }

    public string param2 { get; set; }

    public int pageSize { get; set; }
}

如果你只有这三个参数并且很少使用它们,你也可以这样做:

public async Task<HttpResponseMessage> Get(
    [FromUri(Name="param1")] string parameterOne, 
    [FromUri(Name="param2")] string parameterTwo, 
    [FromUri(Name="pageSize")] int pageSize)

请注意查询字符串名称与方法参数名称的不同之处。

<强>更新

您似乎缺少使用自定义模型绑定器标记方法或类,例如

public async Task<HttpResponseMessage> Get([ModelBinder(typeof(RequestObjectModelBinder)]RequestObject request)

如果你使用一次以上的课程,你也可以标记实际的课程,例如

[ModelBinder(typeof(RequestObjectModelBinder)
public class RequestObject {}

答案 1 :(得分:-2)

试试这个: -

public async Task<HttpResponseMessage> Get([FromUri][ModelBinder]RequestObject request)