Pour .net 4 il pourrait ressembler à:
[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);
}
}
Utilisation:
[MyValidationAttribute(true, Regex = "[a-z]*", StringLength = 3)]
public string Name { get; set; }
Dans .net 3.5 il y a une limite, que vous ne pouvez pas Construire dynamiquement la valeur du message à partir des attributs sous-jacents (au moins, je n'ai pas pu y accéder). Vous ne pouvez définir qu'un seul message par attribut entier.
Tout a changé est à l'intérieur de la méthode 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 à ErrorMessage
:
Valeur de retour de la méthode IsValid
de ValidationAttribute
dans .NET 3.5 n'est pas ValidationResult
mais bool
. Lorsque j'ai essayé de définir le ErrorMessage
, j'ai reçu l'erreur value can be set only once
.
Cela semble très bien, je vais passer un test demain matin. – orangesherbert