宁静的网络API参数为INT
问题描述:
数组在理想情况下,我想有以下格式的URL:宁静的网络API参数为INT
/api/categories/1,2,3...N/products
,这将返回所有产品为指定的类别。使用多个类别ID进行一次API调用可以节省多次数据库调用,从而提高性能。
我可以通过以下方式轻松实现此目的。
public HttpResponseMessage GetProducts(string categoryIdsCsv)
{
// <1> Split and parse categoryIdsCsv
// <2> Get products
}
但是,这看起来不像干净整洁的解决方案,并可能违反SRP原则。我也尝试使用ModelBinder
,但它将参数添加到查询字符串。
问题:
- 有没有实现这样的URL结构的清洁方法是什么?
- 还是有不同/更好的方法来检索所有产品的多个类别?
如果您需要进一步澄清,请让我知道。
答
我刚刚找到了我的问题的答案。 Route
属性在使用ModelBinder
时缺少参数。
[Route("api/categories/{categoryIds}/products")]
public HttpResponseMessage GetProducts([ModelBinder(typeof(CategoryIdsModelBinder))] CategoryIds categoryIds)
{
// <2> Get products using categoryIds.Ids
}
而且CategoryIds
将
public class CategoryIds
{
public List<int> Ids{ get; set; }
}
而且CategoryIdsModelBinder
将
public class CategoryIdsModelBinder : IModelBinder
{
public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
{
if (bindingContext.ModelType != typeof(CategoryIds))
{
return false;
}
var val = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
if (val == null)
{
return false;
}
var key = val.RawValue as string;
if (key == null)
{
bindingContext.ModelState.AddModelError(bindingContext.ModelName, "Wrong value type");
return false;
}
var values = val.AttemptedValue.Split(',');
var ids = new List<int>();
foreach (var value in values)
{
int intValue;
int.TryParse(value.Trim(), out intValue);
if (intValue > 0)
{
ids.Add(intValue);
}
}
if (ids.Count > 0)
{
var result = new CategoryIds
{
Ids= ids
};
bindingContext.Model = result;
return true;
}
bindingContext.ModelState.AddModelError(
bindingContext.ModelName, "Cannot convert value to Location");
return false;
}
答
我们可以用邮方法
[RoutePrefix( “API /类”) 公共类的TestController { [HttpPost] [路线( “的getProducts”)
public HttpResponseMessage GetProducts (HttpRequestMessage request)
{
HttpResponseMessage message = null;
string input = string.Empty;
input = request.Content.ReadAsStringAsync().Result;
var ids = Newtonsoft.Json.JsonConvert.DeserializeObject<List<string>> (input);
}
}
答
不幸Web API无法将数据解析为数组或作为开箱即用的某种自定义对象。
如果要分析您的网址PARAM作为数组,你可以试着这样做:
写自己的路由约束,这将读取并从字符串转换您的参数去整数/字符串/数组什么;
编写您的自定义类型转换器并将其与您的数据模型一起使用;
写你的价值供应商,并与您的数据模型,用它
使用参数绑定
而且你总是可以使用查询参数这是从来没有将打破REST的原则:)
H ope,帮助
这有什么错'/ API /产品?类别[] = 1&类别[] = 2&...' ?这是这种事情的标准方式。此外,Web API 2会自动将这些查询参数解析到控制器方法参数'int [] categories'中,因此不需要定制'ModelBinder'。 –