tl; dr 版本是:我是否可以为Web API方法模拟params
/重载而无需实现自定义IHttpActionSelector?
我很惊讶地发现Web API方法不支持params
(从那以后opened an issue in probably the wrong place)
[HttpPost]
[Route("Test")]
public IHttpActionResult Test([FromBody] params Int32[] values) {
// ...
}
POST
- [1,2,3]
的有效负载按预期工作,但只是4
会导致values
为null
。
所以我决定尝试方法重载。但是,这也不起作用。
[HttpPost]
[Route("Test")]
public IHttpActionResult Test([FromBody] Int32 value) {
return this.Test(new[] { value });
}
[HttpPost]
[Route("Test")]
public IHttpActionResult Test([FromBody] Int32[] values) {
// ...
}
无论有效载荷如何(预计,我猜)都抛出:
找到与请求匹配的多个操作:...
看起来我必须尝试实现一个自定义IHttpActionSelector,但我想知道是否有任何魔法我错过了我可以使用?
答案 0 :(得分:1)
我是否可以模拟Web API方法的params /重载而不必 实现自定义
IHttpActionSelector
?
是强>
这是与模型相关的绑定问题。
创建了以下活页夹和属性。
public class ParamsAttribute : ParameterBindingAttribute {
public override HttpParameterBinding GetBinding(HttpParameterDescriptor parameter) {
//Check to make sure that it is a params array
if (parameter.ParameterType.IsArray &&
parameter.GetCustomAttributes<ParamArrayAttribute>().Count() > 0) {
return new ParamsParameterBinding(parameter);
}
return parameter.BindAsError("invalid params binding");
}
}
public class ParamsParameterBinding : HttpParameterBinding {
public ParamsParameterBinding(HttpParameterDescriptor descriptor)
: base(descriptor) {
}
public override async Task ExecuteBindingAsync(ModelMetadataProvider metadataProvider, HttpActionContext actionContext, CancellationToken cancellationToken) {
var descriptor = this.Descriptor;
var paramName = descriptor.ParameterName;
var arrayType = descriptor.ParameterType;
var elementType = arrayType.GetElementType();
try {
//can it be converted to array
var obj = await actionContext.Request.Content.ReadAsAsync(arrayType);
actionContext.ActionArguments[paramName] = obj;
return;
} catch { }
try {
//Check if single and wrap in array
var obj = await actionContext.Request.Content.ReadAsAsync(elementType);
var array = Array.CreateInstance(elementType, 1);
array.SetValue(obj, 0);
actionContext.ActionArguments[paramName] = array;
return;
} catch { }
}
}
这允许以下内容接受在请求正文中发布的单个和多个值。
[HttpPost]
[Route("Test")]
public IHttpActionResult Test([Params] params Int32[] values) {
// ...
}
POST
- [1,2,3]
的有效负载将按预期工作,只需4就会导致values
为[4]
。
绑定器现在尊重params
修饰符,从而使端点能够接受给定参数的一个或多个。它也适用于非原始对象
[HttpPost]
[Route("Customers")]
public IHttpActionResult Test([Params] params Customer[] customers) {
// do important stuff
}
这可以进一步改进,以将任何集合作为参数来接受单个或多个值,而不仅仅是params
。