我想通过属性向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;
}
}
我所做的:
[ApiController]
属性添加到控制器类,以根据请求激活自动模型验证。System.ComponentModel.DataAnnotations
到项目中。这适用于简单的模型类,但是如果模型是从集合继承的,则不会发生属性验证。
为了解决此问题,我实现了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
调用该方法,这将发生。
如何解决这个问题:
实现IValidatableObject
接口,并在Validate
方法中尝试验证当前实例,并记住退出无限递归。(已在问题中完成)
为模型类创建一个自定义验证属性(从继承ValidationAttribute
),该属性将搜索带有验证属性的属性并独立地对其进行验证。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句