了解DataAnnotations中的ValidationContext

时间:2010-11-30 20:54:14

标签: .net validation .net-4.0 data-annotations

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

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

和方法:

public void CreateUser(string name) {...}

我的验证码是:

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);

name的值为null之前,它可以正常工作。我在实例化ArgumentNullException时得到ValidationContext并且不明白为什么。 TryValidateValue()也要求非空上下文。我有一个值和一个要验证的属性列表。什么是ValidationContext

1 个答案:

答案 0 :(得分: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);
    }
}

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

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

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