如何在ASP.NET Core 3.0中使用ValidationAttribute验证多个操作参数?

3
考虑以下控制器操作的签名:
[HttpGet]
public IEnumerable<Whatever> Get(DateTime from, DateTime to)

或者

[HttpGet]
public Whatever Get(int amount, SomeUnit unit)

我想要能够验证调用者提供的参数。在两种情况下,第一个参数中被视为有效输入的内容都取决于第二个参数的值。
到目前为止,我没有找到在ASP.NET Core 3.0中如何使用验证属性实现这一点的解释或示例。
我看到例如CustomValidationAttribute允许在方法上使用它。我可以给它一个IsValid将委托到的方法,并提供对象和验证上下文:
IsValid(Object, ValidationContext)

我查看了IsValid和ValidationContext的文档,但没有找到任何提示,说明如何访问传递给验证操作的参数。
在搜索提示时,我找到了来自“Pro ASP.NET Web API”ASP.NET中的HTTP Web服务的摘录,他们实现了类似的功能。然而,这段摘录结束之前没有展示代码,而我没有那本书(没有找到相应的书,只有关于ASP.NET Core的书)。
1个回答

3

CustomValidationAttribute 用于属性和参数。若要进行操作验证,您应编写自己的筛选器。以下是一个示例:

public class MyValidationAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext context)
    {
        if(context.ModelState.IsValid)
        {
            var dateFrom = (DateTime)context.ActionArguments["from"];
            var dateTo = (DateTime)context.ActionArguments["to"];

            if(dateFrom <= dateTo)
            {
                // continue the flow in pipeline
                return;
            }
        }

        context.Result = new BadRequestResult();
    }
}

然后你可以在你的控制器中使用它:

[HttpGet]
[MyValidation]
public IEnumerable<Whatever> Get(DateTime from, DateTime to)
{
    // Here ModelState.IsValid is true
}

谢谢您的回答。我看到这个方法可以解决问题,但是我希望asp.net core能提供一个更优雅的解决方案。你知道,我已经有了一个应用于所有控制器的全局ActionFilter,它会检查ModelState是否有效,然后返回我的自定义错误响应以及所有的验证错误。使用您的方法,我不确定我对哪个ActionFilter有多少控制权。如果模型上已经存在一些验证错误,并且我的错误返回过滤器首先执行,那么我可能会向调用者返回不完整的验证错误数量。 - Emil
@Emil,你可以设置过滤器的Order属性。 - svstnv
有没有办法使用现有的验证器?例如 [StringLength(1)] 等? - Yarek T

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接