dotnet核心webapi json-api兼容查询字符串路由

问题描述:

我试图抓住“状态”和“所有”键,来自请求的URL的值,并且无法弄清楚如何构建我的类对象。dotnet核心webapi json-api兼容查询字符串路由

我所指的JSON API规范可以在这里找到: http://jsonapi.org/recommendations/#filtering

// requested url 
/api/endpoint?filter[status]=all 


// my attempt at model binding 
public class FilterParams 
{ 
    public Dictionary<string, string> Filter { get; set; } 
} 

[HttpGet] 
public string Get([FromUri] FilterParams filter) 
{ 
    // never gets populated... 
    var filterStatus = filter.Filter["status"]; 
} 

  1. 您可以使用该IModelBinder

    • 定义模型绑定:

      public class FilterParamsModelBinder : IModelBinder 
      { 
          public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext) 
          { 
           if (bindingContext.ModelType != typeof(FilterParams)) return false; 
      
           Dictionary<string, string> result = new Dictionary<string, string>(); 
      
           var parameters = actionContext.Request.RequestUri.Query.Substring(1); 
      
           if(parameters.Length == 0) return false; 
      
           var regex = new Regex(@"filter\[(?<key>[\w]+)\]=(?<value>[\w^,]+)"); 
      
           parameters 
            .Split('&') 
            .ToList() 
            .ForEach(_ => 
            { 
             var groups = regex.Match(_).Groups; 
      
             if(groups.Count == 0) 
              bindingContext.ModelState.AddModelError(bindingContext.ModelName, "Cannot convert value."); 
      
             result.Add(groups["key"].Value, groups["value"].Value); 
            }); 
      
           bindingContext.Model = new FilterParams { Filter = result}; 
      
           return bindingContext.ModelState.IsValid; 
          } 
      } 
      
    • 使用它:

      [HttpGet] 
      public string Get([ModelBinderAttribute(typeof(FilterParamsModelBinder))] FilterParams filter) 
      { 
          //your code 
      } 
      
  2. 如果你可以定义一个路线,如 “/ API /终点过滤=状态,所有?”,而不是,不是,你可以使用一个TypeConverter

    • 定义转换器:

      public class FilterConverter : TypeConverter 
      { 
          public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) 
          { 
           if (!(value is string)) return base.ConvertFrom(context, culture, value); 
      
           var keyValue = ((string)value).Split(','); 
      
           return new FilterParams 
           { 
            Filter = new Dictionary<string, string> { [keyValue[0]] = keyValue[1] } 
           }; 
          } 
      
          public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) 
          { 
           return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType); 
          }    
      } 
      
    • 使用它:

      [TypeConverter(typeof(FilterConverter))] 
      public class FilterParams 
      { 
          public Dictionary<string, string> Filter { get; set; } 
      } 
      
      [HttpGet] 
      public string Get(FilterParams filter) 
      { 
          var filterStatus = filter.Filter["status"]; 
      } 
      
+0

不,我想坚持到位于JSON API标准:http://jsonapi.org/recommendations/#filtering –

+0

@CarlSagan增加了一个可选的解决方案使用模型绑定器。 –