C# asp.net web API路由中的可选属性

C# asp.net web API路由中的可选属性,c#,asp.net,asp.net-web-api,optional-parameters,C#,Asp.net,Asp.net Web Api,Optional Parameters,我正在使用web api筛选器验证所有传入的视图模型,如果为空,则返回视图状态错误: public class ValidateViewModelAttribute : ActionFilterAttribute { public override void OnActionExecuting(HttpActionContext actionContext) { if(actionContext.ActionArguments != null) {

我正在使用web api筛选器验证所有传入的视图模型,如果为空,则返回视图状态错误:

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);
        }
    }
}
我在生产中使用了web api,现在我收到了一个新的请求,要求在一个操作中添加一个可选参数。可选。。。。保持api兼容性

    [Route("applyorder/{orderId}")]
    [HttpPost]
    public async Task<IHttpActionResult> ApplyOrder(int orderId, [FromBody] ApplyOrderViewModel input = null)
[路由(“applyorder/{orderId}”)]
[HttpPost]
公共异步任务ApplyOrder(int-orderId,[FromBody]ApplyOrderViewModel输入=null)
如果我没有指定输入
=null
,它就不会被视为可选参数,也无法通过验证。由于
=null
我得到以下错误:

“消息”:“出现错误。”,“例外消息”:“可选” “FormatterParameterBinding”不支持参数“input”。,
“异常类型”:“System.InvalidOperationException”,“StackTrace”: 位于System.Web.Http.Controllers.HttpActionBinding.ExecuteBindingAsync(

如何保持全局viewmodel验证,并且仍然将此唯一方法参数标记为可选参数

  • ps:我不能将语法路由与
    符号一起使用,因为它是[FromBody]
  • pss:我不想介绍v2 api,因为它不是v2 api, 我正在添加新的可选参数
  • 我需要某种属性 更新绑定描述符并指定我的参数是 可选,然后它将通过我的验证

由于它是您自己的验证,如果没有
=null
它就无法通过,因此您可以添加一个自定义
[OptionalParameter]
属性并检查它是否存在,例如,尽管您需要按类型进行一些缓存以避免过度使用反射

第二个选项是为下面的所有可选参数设置一些基类,只需使用
is
操作符进行检查

public abstract class OptionalParameter
{
}
第三种选择是对接口执行相同的操作


虽然该属性在我看来是最干净的,但实现起来有点困难。

带有方法参数的属性?因此它将作为
[Optional][FromBody]applyordViewModel input
?我正在考虑调整
[FromBody]
添加将其定义为可选的功能,但该类是密封的,对此我无能为力。基本思想是保持验证不变,但调整我的方法定义,使参数绑定理解它是可选的
argumentBinding?.Descriptor?.isoOptional
是,如您所述的附加属性
[可选]
。您必须使用反射来检查属性是否存在。虽然您似乎已经在那里使用了反射,但是您只需要添加一个简单的属性检查。我想这个建议是最好的实现和使用方法。清晰而优雅:)СаСб