asp.net web API 路由中的可选属性
Optional attribute in asp.net web API routing
我正在使用网络 api 过滤器来验证所有传入的视图模型和 return 视图状态错误(如果它为 null):
public class ValidateViewModelAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
if(actionContext.ActionArguments != null)
{
foreach (var argument in actionContext.ActionArguments)
{
if (argument.Value != null)
continue;
var argumentBinding = actionContext.ActionDescriptor?.ActionBinding.ParameterBindings
.FirstOrDefault(pb => pb.Descriptor.ParameterName == argument.Key);
if(argumentBinding?.Descriptor?.IsOptional ?? true)
continue;
actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.BadRequest, string.Format("Arguments value for {0} cannot be null", argument.Key));
return;
}
}
if (actionContext.ModelState.IsValid == false)
{
actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.BadRequest, actionContext.ModelState);
}
}
}
我的网络 api 正在生产中运行,现在我收到了一个新请求,要为一项操作添加一个可选参数。可选....保持api兼容性
[Route("applyorder/{orderId}")]
[HttpPost]
public async Task<IHttpActionResult> ApplyOrder(int orderId, [FromBody] ApplyOrderViewModel input = null)
如果我不指定输入 = null
它不被认为是可选参数并且无法通过我的验证。使用 = null
我收到以下错误:
"Message": "An error has occurred.", "ExceptionMessage": "Optional
parameter 'input' is not supported by 'FormatterParameterBinding'.",
"ExceptionType": "System.InvalidOperationException", "StackTrace": "
at System.Web.Http.Controllers.HttpActionBinding.ExecuteBindingAsync(
如何保持我的全局视图模型验证到位并仍然将这个唯一的方法参数标记为可选。
- ps:我不能使用带有
?
符号的语法路由,因为它是 [FromBody]
- pss: 我不想介绍 v2 api 因为它不是 v2 api,
我正在添加新的可选参数
- psss: 我需要某种属性
更新绑定描述符并指定我的参数是
可选的,那么它将通过我的验证。
由于您自己的验证不能在没有 = null
的情况下通过,因此您可以添加自定义 [OptionalParameter]
属性并检查它是否存在,例如,尽管您需要按类型进行一些缓存以避免过度使用反射。
第二个选项是为所有可选参数设置一些 Base class,如下所示,只需使用 is
运算符检查即可。
public abstract class OptionalParameter
{
}
第三个选项是对界面执行相同的操作。
虽然我认为该属性是最干净的,但实现起来有点困难。
我正在使用网络 api 过滤器来验证所有传入的视图模型和 return 视图状态错误(如果它为 null):
public class ValidateViewModelAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
if(actionContext.ActionArguments != null)
{
foreach (var argument in actionContext.ActionArguments)
{
if (argument.Value != null)
continue;
var argumentBinding = actionContext.ActionDescriptor?.ActionBinding.ParameterBindings
.FirstOrDefault(pb => pb.Descriptor.ParameterName == argument.Key);
if(argumentBinding?.Descriptor?.IsOptional ?? true)
continue;
actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.BadRequest, string.Format("Arguments value for {0} cannot be null", argument.Key));
return;
}
}
if (actionContext.ModelState.IsValid == false)
{
actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.BadRequest, actionContext.ModelState);
}
}
}
我的网络 api 正在生产中运行,现在我收到了一个新请求,要为一项操作添加一个可选参数。可选....保持api兼容性
[Route("applyorder/{orderId}")]
[HttpPost]
public async Task<IHttpActionResult> ApplyOrder(int orderId, [FromBody] ApplyOrderViewModel input = null)
如果我不指定输入 = null
它不被认为是可选参数并且无法通过我的验证。使用 = null
我收到以下错误:
"Message": "An error has occurred.", "ExceptionMessage": "Optional parameter 'input' is not supported by 'FormatterParameterBinding'.",
"ExceptionType": "System.InvalidOperationException", "StackTrace": " at System.Web.Http.Controllers.HttpActionBinding.ExecuteBindingAsync(
如何保持我的全局视图模型验证到位并仍然将这个唯一的方法参数标记为可选。
- ps:我不能使用带有
?
符号的语法路由,因为它是 [FromBody] - pss: 我不想介绍 v2 api 因为它不是 v2 api, 我正在添加新的可选参数
- psss: 我需要某种属性 更新绑定描述符并指定我的参数是 可选的,那么它将通过我的验证。
由于您自己的验证不能在没有 = null
的情况下通过,因此您可以添加自定义 [OptionalParameter]
属性并检查它是否存在,例如,尽管您需要按类型进行一些缓存以避免过度使用反射。
第二个选项是为所有可选参数设置一些 Base class,如下所示,只需使用 is
运算符检查即可。
public abstract class OptionalParameter
{
}
第三个选项是对界面执行相同的操作。
虽然我认为该属性是最干净的,但实现起来有点困难。