ASP.NET 控制器数据注释验证:类级验证属性调用,就像属性级一样

ASP.NET controller data annotation validation: Class-level validation attribute called as if property-level

提问人:Kile Kasmir Asmussen 提问时间:7/6/2023 更新时间:7/6/2023 访问量:18

问:

我有一些大致相当于以下代码的东西。一个 ed 查询对象,其中包含一个子对象,其中包含一些详细信息,以及一些自定义验证代码,用于将子对象的验证粘附到查询对象上。子对象在类级别上具有验证属性,这导致了问题:POST

class Query : IValidatableObject
{
  [Required]
  public Filter? FilterField { get; set; }

  public IEnumerable<ValidationResult> Validate(ValidationContext context)
  {
    var list = new List<ValidationResult>();
    Validator.TryValidateObject(
      FilterField,
      new ValidationContext(FilterField) {
        MemberName = nameof(FilterField)
      },
      list,
      validateAllProperties: true);
    return list;
  }
}

[IsAnInt(Name = nameof(MyProp))]
class Filter {
  public int MyProp { get; set; }
}

[AttributeUsage(AttributeTargets.Class)]
class IsAnIntAttribute : ValidationAttribute
{
  public string Name { get; init; }

  protected override ValidationResult? IsValid(object? value, ValidationContext validationContext)
  {
    if (validationContext.ObjectType.GetProperty(Name).GetValue(value) is not int)
      return new ValidationResult("not int!", new[] { Name });
    else
      return ValidationResult.Success;
  }
}

现在,当被验证时,在进入该方法时,我希望是.QueryIsAnIntAttribute.IsValidvalidationContext.ObjectTypetypeof(Filter)

单步执行调试器中的代码,我发现在我的测试套件中确实是这种情况,我在 .调用该方法,并将实例传递给构造函数。Validator.TryValidateObjectQueryQuery.ValidateFilterValidationContext

但是,当我将对象用作控制器操作的参数时,事情就崩溃了:Query

[ApiController]
class QueryableController : ControllerBase
{
  [HttpPost("")]
  public async Task<IActionResult> ProcessQuery([FromBody] Query query)
  {
    if (!ModelState.IsValid) return BadRequest(ModelState);
    return NoContent();
  }
}

当我向此端点发出请求并使用我的调试器单步执行时,我发现 设置为父级,因此是,并且该方法以 .POSTIsAnIntAttribute.IsValidvalidationContext.ObjectInstanceQueryvalidationContext.ObjectTypetypeof(Query)NullReferenceException

这是怎么回事?ASP.net 控制器是否使用与 不同的验证调用?它似乎几乎像是在打电话?Validator.TryValidateObjectValidator.TryValidateProperty

如果是这样,为什么?可以改变吗?我应该更改我的代码来解决这个问题吗?

asp.net 验证 数据注释

评论


答: 暂无答案