验证方法参数上的DataAnnotations [英] Validating DataAnnotations on method parameters

查看:92
本文介绍了验证方法参数上的DataAnnotations的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何将数据注释属性与方法参数一起使用?我希望这样做,但不会引发异常。

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 TestValidate([StringLength(5)] string name = "Default: throw exception")
{
    ValidationContext context = new ValidationContext(name);
    Validator.ValidateObject(name, context);
    return name;
}

或者,我知道这会起作用。但是,这没有使用属性约定的便利。

Alternatively, I know this will work. However, this doesn't use the convenience of the attribute convention.

private string TestValidate(string name = "Default: throw exception")
{
    ValidationContext context = new ValidationContext(name);
    Validator.ValidateValue(name, context, new[] { new StringLengthAttribute(5) });
        return name;
}


推荐答案

您的代码,那么您将需要一些反思(请参阅 https://msdn.microsoft.com/zh-cn/library/system.reflection.parameterinfo.attributes(v = vs.110).aspx

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;

许多验证框架只是封装了获得验证属性所需的所有反射。注意:在这种情况下,我使用了 ValidationAttribute 的子类,而不是更具体的 StringLengthAttribute 。调用 GetCustomAttributes()将返回扩展我们要求的基类的任何属性。这样一来,您就可以完全更改方法的属性并添加更多约束,而无需更改任何代码。如果您评估多个参数或删除一个参数,则必须进行一些更改。

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.

您可以从那时起将其做为代码的通用名称具有特定的 MethodInfo 对象通常是相同的。在这种情况下,我可能会做一些更改:

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

这篇关于验证方法参数上的DataAnnotations的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆