Restful Web Api参数作为int数组
本文关键字:int 数组 参数 Web Api Restful | 更新日期: 2023-09-27 18:03:40
理想情况下,我想有一个URL在以下格式:
/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结构?
- 或者是否有一种不同的/更好的方法来检索多个类别的所有产品?
如果需要进一步的说明,请告诉我。
我刚刚找到了我问题的答案。使用ModelBinder
时,Route
属性缺少参数
[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;
}
我们可以使用Post方法
[RoutePrefix ("api/categories")]公共类TestController{(HttpPost)[Route ("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不能将数据解析为数组或某种自定义对象。
如果你想将url参数解析为数组,你可以尝试这样做:
-
写你自己的路由约束,它将读取和转换你的参数从字符串到int/string/任何数组;
-
编写您的自定义类型转换器,并使用它与您的数据模型;
-
写你的值提供者,也使用它与你的数据模型
-
使用参数绑定
此外,您可以始终使用查询参数,这永远不会违反REST原则:)
请查看此处和此处的更多详细信息
希望有帮助