C# Swagger不调用WebAPI自定义ModelBinder

C# Swagger不调用WebAPI自定义ModelBinder,c#,asp.net-web-api2,swagger,C#,Asp.net Web Api2,Swagger,目标:我正在设计一个RESTAPI,它允许用户在HTTP GET请求的查询字符串上传递参数。差不多 public async Task<HttpResponseMessage> Get([ModelBinder]RequestObject request) 实现:在服务器端,我有一个自定义模型绑定器,可以从请求querystring获取参数,并将其转换为C#对象,这样我的控制器操作方法就不必解析查询字符串。 控制器动作方法签名看起来像 public async Task<H

目标:我正在设计一个RESTAPI,它允许用户在HTTP GET请求的查询字符串上传递参数。差不多

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

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

public async Task<HttpResponseMessage> Get([ModelBinder]RequestObject request)
public异步任务Get([ModelBinder]RequestObject请求)
当我从Fiddler测试api并传递querystring值时,自定义模型绑定器工作,我在控制器操作中得到具有正确值的c#对象

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

我怎样才能解决这个问题

我的自定义modelbinder:

   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;
        }
公共类RequestObjectModelBinder:IModelBinder
{
public bool BindModel(HttpActionContext actionContext,ModelBindingContext bindingContext)
{
if(bindingContext.ModelType!=typeof(RequestObject))
{
返回false;
}
var searchCriteria=newrequestobject();
var type=searchCriteria.GetType();
var querystringVals=actionContext.Request.GetQueryNameValuePairs();
var keyValuePairs=querystringVals as IList??querystringVals.ToList();
如果(!keyValuePairs.Any())
{
bindingContext.Model=searchCriteria;
返回true;
}
foreach(keyValuePairs中的var值)
{
var key=value.key;
var prop=type.GetProperty(key,BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);
if(prop==null)
{
继续;
}
prop.SetValue(searchCriteria,Convert.ChangeType(value.value,prop.PropertyType),null);
}
var validationResults=新集合();
var isValid=Validator.TryValidateObject(searchCriteria,new ValidationContext(searchCriteria,null,null),validationResults,true);
如果(!isValid)
{
foreach(validationResults中的var结果)
{
bindingContext.ModelState.AddModelError(“,result.ErrorMessage”);
}
}
bindingContext.Model=searchCriteria;
返回true;
}
试试这个:-

public async Task<HttpResponseMessage> Get([FromUri][ModelBinder]RequestObject request)
public异步任务Get([FromUri][ModelBinder]RequestObject请求)
如果您只有这三个参数,并且它们很少使用,您还可以执行以下操作:

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

否。它不工作。引发以下错误:“消息”:“出现错误”。“ExceptionMessage”:“无法绑定参数‘searchCriteria’,因为它的属性冲突。”我有大约11个属性。我选择了modelbinder,因为如果我在没有任何querystring值的情况下调用该操作,我希望使用默认属性值获取请求。没有modelbinder,它将不起作用。如果您发布自定义模型绑定器,我们可以诊断发生这种情况的原因。您是否创建了自定义模型绑定器?是的。我已更新我用自定义modelbinder发布的帖子。当我在action方法中使用[FromUri]时,对象为null。这可能是因为我使用的是[Route(“”)?我使用了自定义ModelBinderProvider,并在WebAPIConfig中进行了配置。如果您查看swagger执行的URL,它是否包含变量的前缀,例如
request.param1
?我怀疑如果它是手动工作的,但不是通过swagger进行配置的。通常通过
[FromUri(Name=”“)解决此问题
但在这种情况下,它不起作用。
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 {}