2016-11-12 4 views
2

リクエストされたURLから「ステータス」キーと「すべて」キーの値を取得しようとしていますが、クラスオブジェクトをビルドする方法がわかりません。dotnet core 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"]; 
} 

答えて

0
  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. をあなたはそのためのTypeConverter使用できるよりもあなたが、代わりに "/ API /エンドポイントのフィルタ=ステータス、すべての?" のようなルートを定義することができた場合:

    • コンバータを定義します。

      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代替ソリューションを追加しましたモデルバインダーを使用します。 –