数据注释属性如何与方法参数一起使用?我期待做这样的事情,但不会抛出异常。
private string TestValidate([StringLength(5)] string name = "Default: throw exception")
{
ValidationContext context = new ValidationContext(name);
Validator.ValidateObject(name, context);
return name;
}
或者,我知道这会奏效。但是,这并没有使用属性约定的便利性。
private string TestValidate(string name = "Default: throw exception")
{
ValidationContext context = new ValidationContext(name);
Validator.ValidateValue(name, context, new[] { new StringLengthAttribute(5) });
return name;
}
答案 0 :(得分:0)
如果您想要修改代码,那么您可以使用一些反思(请参阅https://msdn.microsoft.com/en-us/library/system.reflection.parameterinfo.attributes(v=vs.110).aspx)
您可以在类初始化时评估一次反射,但这就是反射代码的工作方式:
// 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()
的调用将返回扩展我们要求的基类的任何属性。这允许您完全更改方法上的属性并添加更多约束而无需更改代码。如果您评估多个参数或删除参数,则必须进行一些更改。
您可以使这一点更通用,因为您拥有特定MethodInfo
对象时的代码通常是相同的。在这种情况下,我可能会做一些改变:
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);
}
}