我有一个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
当前回答
public class ArrayInputAttribute : ActionFilterAttribute
{
private readonly string[] _ParameterNames;
/// <summary>
///
/// </summary>
public string Separator { get; set; }
/// <summary>
/// cons
/// </summary>
/// <param name="parameterName"></param>
public ArrayInputAttribute(params string[] parameterName)
{
_ParameterNames = parameterName;
Separator = ",";
}
/// <summary>
///
/// </summary>
public void ProcessArrayInput(HttpActionContext actionContext, string parameterName)
{
if (actionContext.ActionArguments.ContainsKey(parameterName))
{
var parameterDescriptor = actionContext.ActionDescriptor.GetParameters().FirstOrDefault(p => p.ParameterName == parameterName);
if (parameterDescriptor != null && parameterDescriptor.ParameterType.IsArray)
{
var type = parameterDescriptor.ParameterType.GetElementType();
var parameters = String.Empty;
if (actionContext.ControllerContext.RouteData.Values.ContainsKey(parameterName))
{
parameters = (string)actionContext.ControllerContext.RouteData.Values[parameterName];
}
else
{
var queryString = actionContext.ControllerContext.Request.RequestUri.ParseQueryString();
if (queryString[parameterName] != null)
{
parameters = queryString[parameterName];
}
}
var values = parameters.Split(new[] { Separator }, StringSplitOptions.RemoveEmptyEntries)
.Select(TypeDescriptor.GetConverter(type).ConvertFromString).ToArray();
var typedValues = Array.CreateInstance(type, values.Length);
values.CopyTo(typedValues, 0);
actionContext.ActionArguments[parameterName] = typedValues;
}
}
}
public override void OnActionExecuting(HttpActionContext actionContext)
{
_ParameterNames.ForEach(parameterName => ProcessArrayInput(actionContext, parameterName));
}
}
用法:
[HttpDelete]
[ArrayInput("tagIDs")]
[Route("api/v1/files/{fileID}/tags/{tagIDs}")]
public HttpResponseMessage RemoveFileTags(Guid fileID, Guid[] tagIDs)
{
_FileRepository.RemoveFileTags(fileID, tagIDs);
return Request.CreateResponse(HttpStatusCode.OK);
}
请求uri
http://localhost/api/v1/files/2a9937c7-8201-59b7-bc8d-11a9178895d0/tags/BBA5CD5D-F07D-47A9-8DEE-D19F5FA65F63,BBA5CD5D-F07D-47A9-8DEE-D19F5FA65F63
其他回答
正如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数组。
将方法类型设置为[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);
你只需要在参数前添加[FromUri],看起来像:
GetCategories([FromUri] int[] categoryIds)
并发送请求:
/Categories?categoryids=1&categoryids=2&categoryids=3
所有其他解决方案都需要大量的工作。我试图在HttpGet方法参数中使用IEnumerable<long>或long[],但我认为没有必要做所有的工作,只是为了使处理程序方法参数的签名long[]。我最终只是把它变成字符串,然后在处理程序中把它分开。我只说了一句。
public async Task<IActionResult> SomeHandler(string idsString)
{
var ids = idsString.Split(',').Select(x => long.Parse(x));
现在你可以传递这些数字
.../SomeHandler?idsString=123,456,789,012
简单的方法发送数组参数到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