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"];
}
答
-
您可以使用该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 }
-
-
如果你可以定义一个路线,如 “/ 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"]; }
-
不,我想坚持到位于JSON API标准:http://jsonapi.org/recommendations/#filtering –
@CarlSagan增加了一个可选的解决方案使用模型绑定器。 –