.net 了解 DataAnnotations 中的 ValidationContext

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4318524/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 14:59:13  来源:igfitidea点击:

Understanding ValidationContext in DataAnnotations

.netvalidation.net-4.0data-annotations

提问by UserControl

I want to utilize Validator.TryValidateValue()but don't understand the mechanics. Say, i have the following:

我想使用Validator.TryValidateValue()但不了解机制。说,我有以下几点:

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

and the method:

和方法:

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

My validation code is:

我的验证码是:

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

It works fine until value of nameis null. I'm getting ArgumentNullExceptionwhen instantiating ValidationContextand don't understand why. TryValidateValue()also demands non-null context. I have a value and a list of attributes to validate against. What is that ValidationContextfor?

它工作正常,直到值为nameis nullArgumentNullException实例化时我得到了ValidationContext,但不明白为什么。TryValidateValue()还需要非空上下文。我有一个值和一个要验证的属性列表。那是ValidationContext为了什么?

采纳答案by Cylon Cat

The only thing that's wrong about your code is the instance object for your validation context. The instance does not need to be the value that's being validated. For Validator.ValidateProperty, yes, it does need to be the object that owns the property, but for Validator.ValidateValue, "this" is sufficient.

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

I wrote a validation helper class to do the setup; this lets me pass in arbitrary values from anywhere.

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

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

If you are validating properties that have the validation attributes on the property, it's a lot easier:

如果您正在验证在属性上具有验证属性的属性,则要容易得多:

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

"Entity" is a property of the current class that references the object that I want to validate. This lets me validate properties on other objects. If you're already inside the objct, "this" will again be sufficient.

“实体”是当前类的一个属性,它引用了我要验证的对象。这让我可以验证其他对象的属性。如果您已经在对象中,“this”就足够了。