为什么自动属性验证不适用于继承集合的模型?



我想通过属性将模型验证添加到Web API(.NET Framework 4.7.2(,但我遇到了这样一个事实,即如果模型是集合,则此操作不起作用。

我有一个从字典中继承的模型类。例如:

...
using System.ComponentModel.DataAnnotations;
...
public class MyModel : Dictionary<string, string>
{
[StringLength(100)]
public string SomeField
{
get => TryGetValue("someField", out var value) ? value : null;
set => this["someField"] = value;
}
}

我所做的:

  1. [ApiController]属性添加到控制器类,以在请求时激活自动模型验证
  2. System.ComponentModel.DataAnnotations添加到项目中
  3. 为模型字段添加了验证属性

这适用于简单的模型类,但如果模型是从集合继承的,则不会进行属性验证。

为了解决这个问题,我实现了IValidatableObject接口,在那里我写了以下内容:

public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
const string validationStatusFieldName = "alreadyValidated";
if (validationContext.Items.TryGetValue(validationStatusFieldName, out var alreadyValidated) && (bool) alreadyValidated)
return Enumerable.Empty<ValidationResult>();
validationContext.Items[validationStatusFieldName] = true;
var validationResults = new List<ValidationResult>();
var isValid = Validator.TryValidateObject(validationContext.ObjectInstance, validationContext, validationResults, true);
return isValid
? Enumerable.Empty<ValidationResult>()
: validationResults;
}

在这种情况下,会自动调用Validate方法,在那里我们可以手动验证属性。但是,如果属性验证通过而没有验证错误,那么Validate方法将被调用,在这种情况下,Validate方法会一次又一次地调用自己,从而导致堆栈溢出异常。因此,我添加了一个检查,以确保验证已经进行。

因此,它是有效的,但还不清楚:如果这个模型继承了一个集合,为什么不自动检查属性,以及如何解决它?

验证器有一个条件,在这个条件下,他可以选择如何验证对象。首先检查模型是否为集合,然后检查其每个元素。由于此集合存储没有验证约束的字符串,因此验证过程中不会有任何注释。如果通过属性进行字段验证没有问题,那么就会调用Validate方法,这就是实际情况。

如何绕过这一点:

  • 实现IValidatableObject接口,在Validate方法中,尝试验证当前实例,记住退出无限递归(在问题中完成(

  • 为模型类创建一个自定义验证属性(继承自ValidationAttribute(,该属性将搜索具有验证属性的属性并独立验证它们。

相关内容

  • 没有找到相关文章

最新更新