[英]Custom validation attribute calling another validation attribute
I want to create a custom validation attribute that calls other validation attributes. 我想创建一个调用其他验证属性的自定义验证属性。
For example I want to create an attribute called PasswordValidationAttribute
. 例如,我想创建一个名为PasswordValidationAttribute
的属性。 I want it to decorate the property it is defined on with RequiredAttribute
, RegularExpressionAttribute
and StringLengthAttribute
with various parameters defined (such as the regular expression for a password and a maximum and minimum string length). 我希望它使用RequiredAttribute
, RegularExpressionAttribute
和StringLengthAttribute
来定义它所定义的属性,并定义了各种参数(例如密码的正则表达式以及最大和最小字符串长度)。
I'm struggling on where to begin, ascertain how much work is involved and determine if it is at all possible. 我正在努力从哪里开始,确定涉及多少工作并确定它是否完全可能。 Once this attribute is applied to a property I would like it to process the ValidationMessageFor
HtmlHelper
correctly and do a serverside call. 将此属性应用于属性后,我希望它正确处理ValidationMessageFor
HtmlHelper
并执行服务器端调用。 I'm hoping I don't need to redefine them (otherwise it will be too much work). 我希望我不需要重新定义它们(否则它将是太多的工作)。
For .net 4 it could look like: 对于.net 4,它可能看起来像:
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
public class MyValidationAttribute : ValidationAttribute
{
private readonly bool isRequired;
public string Regex { get; set; }
public int StringLength { get; set; }
public MyValidationAttribute(bool isRequired)
{
this.isRequired = isRequired;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var composedAttributes = ConstructAttributes().ToArray();
if (composedAttributes.Length == 0) return ValidationResult.Success;
var errorMsgBuilder = new StringBuilder();
foreach (var attribute in composedAttributes)
{
var valRes = attribute.GetValidationResult(value, validationContext);
if (valRes != null && !string.IsNullOrWhiteSpace(valRes.ErrorMessage))
errorMsgBuilder.AppendLine(valRes.ErrorMessage);
}
var msg = errorMsgBuilder.ToString();
if (string.IsNullOrWhiteSpace(msg))
return ValidationResult.Success;
return new ValidationResult(msg);
}
private IEnumerable<ValidationAttribute> ConstructAttributes()
{
if (isRequired)
yield return new RequiredAttribute();
if (Regex != null)
yield return new RegularExpressionAttribute(Regex);
if (StringLength > 0)
yield return new StringLengthAttribute(StringLength);
}
}
Usage: 用法:
[MyValidationAttribute(true, Regex = "[a-z]*", StringLength = 3)]
public string Name { get; set; }
In .net 3.5 there is a limitation, that you cannot dynamically construct the message value from underlying attributes ( at least I was not able get to through it ). 在.net 3.5中有一个限制,你不能从底层属性动态构造消息值( 至少我无法通过它 )。 You can set only one message per whole attribute. 每个属性只能设置一条消息。
Everything changed is inside method IsValid
. 改变的一切都是方法IsValid
。
public override bool IsValid(object value)
{
var composedAttributes = ConstructAttributes().ToArray();
if (composedAttributes.Length == 0) return true;
return composedAttributes.All(a => a.IsValid(value));
}
Note to ErrorMessage
: ErrorMessage
注意事项:
Return value of IsValid
method of ValidationAttribute
in .net 3.5 is not ValidationResult
but bool
. .net 3.5中ValidationAttribute
的IsValid
方法的返回值不是ValidationResult
而是bool
。 When I tried to set the ErrorMessage
, I got the error that value can be set only once
. 当我尝试设置ErrorMessage
,我得到的错误是该value can be set only once
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.