了解DataAnnotations中的ValidationContext

Use*_*rol 19 .net validation .net-4.0 data-annotations

我想利用Validator.TryValidateValue()但不了解机制.说,我有以下内容:

public class User {
    [Required(AllowEmptyStrings = false)]
    [StringLength(6)]
    public string Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

和方法:

public void CreateUser(string name) {...}
Run Code Online (Sandbox Code Playgroud)

我的验证码是:

ValidationAttribute[] attrs = bit of reflection here to populate from User class
var ctx = new ValidationContext(name, null, null);
var errors = new List<ValidationResult>();
bool valid = Validator.TryValidateValue(name, ctx, errors, attrs);
Run Code Online (Sandbox Code Playgroud)

它工作正常,直到值namenull.我ArgumentNullException在实例化时得到ValidationContext并且不明白为什么.TryValidateValue()还要求非空上下文.我有一个值和一个要验证的属性列表.这是ValidationContext为了什么?

Cyl*_*Cat 18

您的代码唯一错误的是验证上下文的实例对象.实例不需要是要验证的值.对于Validator.ValidateProperty,是的,它确实需要是拥有该属性的对象,但对于Validator.ValidateValue,"this"就足够了.

我写了一个验证助手类来进行设置; 这让我可以从任何地方传递任意值.

public class ValidationHelper
{
    private List<ValidationResult> m_validationResults = new List<ValidationResult>();
    private List<ValidationAttribute> m_validationAttributes = new List<ValidationAttribute>();

    public Tuple<bool, List<string>> ValidateDOB(DateTime? dob)
    {
        m_validationAttributes.Add(new CustomValidationAttribute(typeof(DateOfBirthValidator), "ValidateDateOfBirth"));
        bool result = Validator.TryValidateValue(dob, 
                             new ValidationContext(this, null, null), 
                             m_validationResults, 
                             m_validationAttributes);
        if (result)
        {
            return Tuple.Create(true, new List<string>());
        }
        List<string> errors = m_validationResults.Select(vr => vr.ErrorMessage).ToList();
        return Tuple.Create(false, errors);
    }
}
Run Code Online (Sandbox Code Playgroud)

如果要验证属性上具有验证属性的属性,则更容易:

internal void Validate(T value)
{
    if (!m_Initializing && TrackChanges && !Entity.IsImmutable)
    {
        Validator.ValidateProperty(value, new ValidationContext(Entity, null, null) { MemberName = PropertyName ?? ModelName });
    }
}
Run Code Online (Sandbox Code Playgroud)

"Entity"是当前类的属性,它引用了我要验证的对象.这让我可以验证其他对象的属性.如果你已经进入了对象,那么"这个"就足够了.

  • @UserControl这是一篇由创建者之一解释ValidationContext的博客文章:http://jeffhandley.com/archive/2010/10/25/RiaServicesValidationContext.aspx (4认同)
  • 谢谢!对象实例对于验证对象和属性是有意义的,但更不用说验证值,并且在所有情况下它都是相同的ValidationContext类.通过逐步调试Visual Studio调试器中的源代码,您可以深入了解设计者的意图.有关下载源代码和设置Visual Studio以调试.NET框架类的说明,请参阅http://referencesource.microsoft.com/. (3认同)