SB2*_*055 9 routes asp.net-web-api asp.net-web-api-routing
我正在关注Web API 2中的属性路由文章,尝试通过URI发送数组:
[HttpPost("api/set/copy/{ids}")]
public HttpResponseMessage CopySet([FromUri]int[] ids)
Run Code Online (Sandbox Code Playgroud)
这在使用基于约定的路由时起作用:
http://localhost:24144/api/set/copy/?ids=1&ids=2&ids=3
Run Code Online (Sandbox Code Playgroud)
但是使用属性路由它不再有效 - 我找不到404.
如果我试试这个:
http://localhost:24144/api/set/copy/1
Run Code Online (Sandbox Code Playgroud)
然后它工作 - 我得到一个元素的数组.
如何以这种方式使用属性路由?
Kir*_*lla 13
您注意到的行为与操作选择和模型绑定而非属性路由更相关.
如果您希望'ids'来自查询字符串,那么请修改您的路由模板,如下所示(因为您定义它的方式会使uri路径中的'ids'成为必需的):
[HttpPost("api/set/copy")]
Run Code Online (Sandbox Code Playgroud)
看看你的第二个问题,你是否想要接受uri本身的id列表,比如api/set/copy/[1,2,3]?如果是的话,我不认为web api内置了对这种模型绑定的支持.
你可以实现一个像下面这样的自定义参数绑定来实现它(我猜有其他更好的方法来实现这一点,比如通过模型绑定器和值提供者,但我不太了解它们......所以你可能需要探索这些选项也是):
[HttpPost("api/set/copy/{ids}")]
public HttpResponseMessage CopySet([CustomParamBinding]int[] ids)
Run Code Online (Sandbox Code Playgroud)
例:
[AttributeUsage(AttributeTargets.Parameter, Inherited = false, AllowMultiple = false)]
public class CustomParamBindingAttribute : ParameterBindingAttribute
{
public override HttpParameterBinding GetBinding(HttpParameterDescriptor paramDesc)
{
return new CustomParamBinding(paramDesc);
}
}
public class CustomParamBinding : HttpParameterBinding
{
public CustomParamBinding(HttpParameterDescriptor paramDesc) : base(paramDesc) { }
public override bool WillReadBody
{
get
{
return false;
}
}
public override Task ExecuteBindingAsync(ModelMetadataProvider metadataProvider, HttpActionContext actionContext,
CancellationToken cancellationToken)
{
//TODO: VALIDATION & ERROR CHECKS
string idsAsString = actionContext.Request.GetRouteData().Values["ids"].ToString();
idsAsString = idsAsString.Trim('[', ']');
IEnumerable<string> ids = idsAsString.Split(',');
ids = ids.Where(str => !string.IsNullOrEmpty(str));
IEnumerable<int> idList = ids.Select(strId =>
{
if (string.IsNullOrEmpty(strId)) return -1;
return Convert.ToInt32(strId);
}).ToArray();
SetValue(actionContext, idList);
TaskCompletionSource<object> tcs = new TaskCompletionSource<object>();
tcs.SetResult(null);
return tcs.Task;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
10190 次 |
| 最近记录: |