Validating DataAnnotations on method parameters

前端 未结 1 1691
小蘑菇
小蘑菇 2021-01-24 20:02

How are data annotation attributes to be used with method parameters? I\'m expecting to do something like this, but an exception isn\'t thrown.

private string Te         


        
相关标签:
1条回答
  • 2021-01-24 20:30

    If you are wanting to instrument your code, then you'd use a bit of reflection (see https://msdn.microsoft.com/en-us/library/system.reflection.parameterinfo.attributes(v=vs.110).aspx)

    You can evaluate your reflection once on class initialization, but this is how the reflection code would work:

    // NOTE: nameof() is a .NET 4.6 feature.  If you are using an older
    // version of .NET, you'll have to write the string yourself.
    MethodInfo method = GetType().GetMethod(nameof(TestValidate), typeof(string));
    // NOTE: it's on you to validate this and use the version with binding flags for
    // special cases like non-public and static methods
    
    ParameterInfo parameter = method.GetParameters().First();
    // This is shorthand: GetCustomAttributes returns object[], you'll have
    // convert that properly and reference your customAttributes later
    ValidationAttribute[] customAttributes = parameter.GetCustomAttributes(
            typeof(ValidationAttribute), true); // second parameter ignored
    
    // At this point you can handle the rest of your validation
    ValidationContext context = new ValidationContext(name);
    Validator.ValidateValue(name, context, customAttributes);
        return name;
    

    Many validation frameworks simply encapsulate all the reflection necessary to get at the validation attributes. NOTE: in this case I used the subclass of ValidationAttribute as opposed to the more specific StringLengthAttribute. The call to GetCustomAttributes() will return any attribute that extends the base class we asked for. That allows you to completely change the attributes you have on your method and add more constraints without changing the code at all. You'll have to make some changes if you evaluate more than one parameter or remove a parameter.

    You could make this a bit more generic as the code from the time you have a specific MethodInfo object would be generally the same. I'd probably make a couple changes in that case:

    public static void Validate(MethodInfo method, params object[] values)
    {
        ValidationContext context = new ValidationContext(method.Name);
        ParameterInfo[] parameters = method.GetParameters();
    
        for(int i = 0; i < Math.Min(parameters.Length, values.Length); i++)
        {
            // This is shorthand: GetCustomAttributes returns object[], you'll have
            // convert that properly and reference your customAttributes later
            ValidationAttribute[] customAttributes = parameter[i].GetCustomAttributes(
                    typeof(ValidationAttribute), true); // second parameter ignored
    
            Validator.ValidateValue(values[i], context, customAttributes);
        }
    }
    
    0 讨论(0)
提交回复
热议问题