我有一个ASP。NET Web API(版本4)REST服务,我需要传递一个整数数组。
下面是我的动作方法:
public IEnumerable<Category> GetCategories(int[] categoryIds){
// code to retrieve categories from database
}
这是我试过的网址:
/Categories?categoryids=1,2,3,4
我有一个ASP。NET Web API(版本4)REST服务,我需要传递一个整数数组。
下面是我的动作方法:
public IEnumerable<Category> GetCategories(int[] categoryIds){
// code to retrieve categories from database
}
这是我试过的网址:
/Categories?categoryids=1,2,3,4
当前回答
简单的方法发送数组参数到web api
API
public IEnumerable<Category> GetCategories([FromUri]int[] categoryIds){
// code to retrieve categories from database
}
Jquery:发送JSON对象作为请求参数
$.get('api/categories/GetCategories',{categoryIds:[1,2,3,4]}).done(function(response){
console.log(response);
//success response
});
它会生成你的请求URL . . / api /类别/ GetCategories吗?categoryid = 1 &categoryids = 2 &categoryids = 3 &categoryids = 4
其他回答
我已经创建了一个自定义模型绑定器,它将任何逗号分隔的值(仅为原语、十进制、浮点数、字符串)转换为相应的数组。
public class CommaSeparatedToArrayBinder<T> : IModelBinder
{
public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
{
Type type = typeof(T);
if (type.IsPrimitive || type == typeof(Decimal) || type == typeof(String) || type == typeof(float))
{
ValueProviderResult val = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
if (val == null) return false;
string key = val.RawValue as string;
if (key == null) { bindingContext.ModelState.AddModelError(bindingContext.ModelName, "Wrong value type"); return false; }
string[] values = key.Split(',');
IEnumerable<T> result = this.ConvertToDesiredList(values).ToArray();
bindingContext.Model = result;
return true;
}
bindingContext.ModelState.AddModelError(bindingContext.ModelName, "Only primitive, decimal, string and float data types are allowed...");
return false;
}
private IEnumerable<T> ConvertToDesiredArray(string[] values)
{
foreach (string value in values)
{
var val = (T)Convert.ChangeType(value, typeof(T));
yield return val;
}
}
}
以及如何在Controller中使用:
public IHttpActionResult Get([ModelBinder(BinderType = typeof(CommaSeparatedToArrayBinder<int>))] int[] ids)
{
return Ok(ids);
}
正如Filip W指出的那样,你可能不得不求助于这样的自定义模型绑定器(修改为绑定到实际的参数类型):
public IEnumerable<Category> GetCategories([ModelBinder(typeof(CommaDelimitedArrayModelBinder))]long[] categoryIds)
{
// do your thing
}
public class CommaDelimitedArrayModelBinder : IModelBinder
{
public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
{
var key = bindingContext.ModelName;
var val = bindingContext.ValueProvider.GetValue(key);
if (val != null)
{
var s = val.AttemptedValue;
if (s != null)
{
var elementType = bindingContext.ModelType.GetElementType();
var converter = TypeDescriptor.GetConverter(elementType);
var values = Array.ConvertAll(s.Split(new[] { ","},StringSplitOptions.RemoveEmptyEntries),
x => { return converter.ConvertFromString(x != null ? x.Trim() : x); });
var typedValues = Array.CreateInstance(elementType, values.Length);
values.CopyTo(typedValues, 0);
bindingContext.Model = typedValues;
}
else
{
// change this line to null if you prefer nulls to empty arrays
bindingContext.Model = Array.CreateInstance(bindingContext.ModelType.GetElementType(), 0);
}
return true;
}
return false;
}
}
然后你可以说:
/类别?categoryids=1,2,3,4和ASP。NET Web API将正确绑定您的categoryIds数组。
或者,您可以只传递一串分隔项,并将其放入接收端的数组或列表中。
我最近遇到了这个需求,我决定实现一个ActionFilter来处理这个问题。
public class ArrayInputAttribute : ActionFilterAttribute
{
private readonly string _parameterName;
public ArrayInputAttribute(string parameterName)
{
_parameterName = parameterName;
Separator = ',';
}
public override void OnActionExecuting(HttpActionContext actionContext)
{
if (actionContext.ActionArguments.ContainsKey(_parameterName))
{
string parameters = string.Empty;
if (actionContext.ControllerContext.RouteData.Values.ContainsKey(_parameterName))
parameters = (string) actionContext.ControllerContext.RouteData.Values[_parameterName];
else if (actionContext.ControllerContext.Request.RequestUri.ParseQueryString()[_parameterName] != null)
parameters = actionContext.ControllerContext.Request.RequestUri.ParseQueryString()[_parameterName];
actionContext.ActionArguments[_parameterName] = parameters.Split(Separator).Select(int.Parse).ToArray();
}
}
public char Separator { get; set; }
}
我像这样应用它(注意,我使用'id',而不是'ids',因为这是如何在我的路由中指定的):
[ArrayInput("id", Separator = ';')]
public IEnumerable<Measure> Get(int[] id)
{
return id.Select(i => GetData(i));
}
public url是:
/api/Data/1;2;3;4
您可能必须对其进行重构以满足您的特定需求。
将方法类型设置为[HttpPost],创建一个有一个int[]参数的模型,并使用json post:
/* Model */
public class CategoryRequestModel
{
public int[] Categories { get; set; }
}
/* WebApi */
[HttpPost]
public HttpResponseMessage GetCategories(CategoryRequestModel model)
{
HttpResponseMessage resp = null;
try
{
var categories = //your code to get categories
resp = Request.CreateResponse(HttpStatusCode.OK, categories);
}
catch(Exception ex)
{
resp = Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex);
}
return resp;
}
/* jQuery */
var ajaxSettings = {
type: 'POST',
url: '/Categories',
data: JSON.serialize({Categories: [1,2,3,4]}),
contentType: 'application/json',
success: function(data, textStatus, jqXHR)
{
//get categories from data
}
};
$.ajax(ajaxSettings);