自定义验证属性调用另一个验证属性 [英] Custom validation attribute calling another validation attribute
问题描述
我要创建一个调用其他验证属性自定义验证属性。
I want to create a custom validation attribute that calls other validation attributes.
例如我想创建一个名为 PasswordValidationAttribute
属性。我想它来装饰它与 RequiredAttribute标签
, RegularEx pressionAttribute
和<$ C $上定义的属性C> StringLengthAttribute 与自定义(如常规的前pression密码和一个最大和最小字符串长度)的各种参数。
For example I want to create an attribute called 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).
我挣扎在哪里开始,确定多少工作是参与,并确定它是否在所有可能的。一旦这个属性应用于一个属性我想它的 ValidationMessageFor
的HtmlHelper
正确处理,并做了服务器端调用。我希望我不需要重新定义它们(否则会被太多的工作)。
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. I'm hoping I don't need to redefine them (otherwise it will be too much work).
推荐答案
对于 .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);
}
}
用法:
[MyValidationAttribute(true, Regex = "[a-z]*", StringLength = 3)]
public string Name { get; set; }
在 .NET 3.5 有一个限制,你不能动态构造从根本属性的消息值(至少我是不是能够得到通过它的)。您可以设置每个整属性只有一个消息。
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). You can set only one message per whole attribute.
一切都改变了里面的方法的IsValid
。
Everything changed is inside method IsValid
.
public override bool IsValid(object value)
{
var composedAttributes = ConstructAttributes().ToArray();
if (composedAttributes.Length == 0) return true;
return composedAttributes.All(a => a.IsValid(value));
}
的注意,以的ErrorMessage
:的
在.NET 3.5 ValidationAttribute
的的IsValid
方法的返回值是不是为ValidationResult
,但布尔
。当我试图将的ErrorMessage
,我得到了值只能设置一次错误
。
Return value of IsValid
method of ValidationAttribute
in .net 3.5 is not ValidationResult
but bool
. When I tried to set the ErrorMessage
, I got the error that value can be set only once
.
这篇关于自定义验证属性调用另一个验证属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!