2016-06-08 64 views
1

目标:我正在设计一个REST API,它允许用户在HTTP GET请求的查询字符串上传递参数。喜欢的东西Swagger未调用WebAPI Custom ModelBinder

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

实施:在服务器端我有一个自定义的模型绑定是得到请求的查询字符串参数,并将其转换为C#对象,这样我的控制器的操作方法并没有解析请求参数。 所以控制器的操作方法的签名看起来像

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

当我测试从提琴手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

试试这个: -

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

不,它不起作用。抛出以下错误:“消息”:“发生错误。”,“ExceptionMessage”:“无法绑定参数'searchCriteria',因为它具有冲突的属性。” –

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 {} 
+0

我有大约11个属性。我去modelbinder,因为如果我没有任何查询字符串值调用操作,我想用默认属性值获取请求。没有modelbinder它不起作用。 –

+0

如果您发布您的自定义模型绑定器,我们可以诊断为什么发生这种情况。您是否创建了自定义模型联编程序? – Mig

+0

是的。我用自定义模型绑定器更新了我的帖子。当我在action方法中使用[FromUri]时,对象为空。难道是因为我正在使用[Route(“”)]? –