问题描述
在ASP.NET Web API接口项目的开发中,接收参数是几乎每个接口都会遇到的问题。
我们知道,传递参数的数据类型有很多种,如:数字,字符串,布尔值,数组,JSON等等。
那么,在ASP.NET Web API中如何接收外部传递的数组呢?比如有以下的action
方法:
public IEnumerable<Category> GetCategories(int[] categoryIds){
// 逻辑代码
}
请求的URL
路径可能为:
/Categories?categoryids=1,2,3,4
方案一
在传递的参数名前添加参数绑定属性[FromUri]
,如下:
GetCategories([FromUri] int[] categoryIds)
请求的路径及参数:
/Categories?categoryids=1&categoryids=2&categoryids=3
方案二
自定义实现一个模型绑定器ModelBinder
,如下:
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
{
bindingContext.Model = Array.CreateInstance(bindingContext.ModelType.GetElementType(), 0);
}
return true;
}
return false;
}
}
控制器中的action
方法:
public IEnumerable<Category> GetCategories([ModelBinder(typeof(CommaDelimitedArrayModelBinder))]long[] categoryIds)
{
// 处理你的业务逻辑
}
访问路径及参数:
/Categories?categoryids=1,2,3,4
方案三
实现一个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; }
}
控制器中的action
方法:
[ArrayInput("id", Separator = ';')]
public IEnumerable<Measure> Get(int[] id)
{
return id.Select(i => GetData(i));
}
访问路径及参数:
/api/Data/1;2;3;4
版权声明:本作品系原创,版权归码友网所有,如未经许可,禁止任何形式转载,违者必究。
发表评论
登录用户才能发表评论, 请 登 录 或者 注册