web-dev-qa-db-fra.com

Comment créer des validateurs d'annotation de données personnalisés

Vouloir créer une validation d'annotation de données personnalisée. Existe-t-il des guides/échantillons utiles sur la façon de les créer?

D'abord:
StringLength avec une longueur minimale et maximale. Je suis conscient que .NET 4 peut le faire, mais je veux faire la même chose dans .NET 3.5, si possible être en mesure de définir uniquement la longueur minimale (au moins x caractères), la longueur maximale uniquement (jusqu'à x caractères), ou les deux (entre x et y caractères).

Deuxièmement:
Validation en utilisant l'arithmétique du module - si le nombre est une longueur valide, je souhaite valider en utilisant l'algorithme Modulus 11 (je l'ai déjà implémenté en JavaScript, donc je suppose que ce ne serait qu'un simple portage?)

Mise à jour:
.

40
SamWM

Pour créer un validateur d'annotation de données personnalisé, suivez ces instructions:

  1. Votre classe doit hériter de la classe System.ComponentModel.DataAnnotations.ValidationAttribute.
  2. Substituez la méthode bool IsValid(object value) et implémentez la logique de validation à l'intérieur.

C'est ça.

IMPORTANT ATTENTION

Parfois, les développeurs vérifient que la valeur n'est pas nulle/vide et retournent faux. C'est généralement un comportement incorrect, car c'est sur le validateur Required pour vérifier ce qui signifie que vos validateurs personnalisés ne doivent valider que les données non nulles mais retourner true sinon (voir exemple). Cela les rendra utilisables sur les champs obligatoires (obligatoires) et non obligatoires.

Exemple

public class StringLengthRangeAttribute : ValidationAttribute
{
    public int Minimum { get; set; }
    public int Maximum { get; set; }

    public StringLengthRangeAttribute()
    {
        this.Minimum = 0;
        this.Maximum = int.MaxValue;
    }

    public override bool IsValid(object value)
    {
        string strValue = value as string;
        if (!string.IsNullOrEmpty(strValue))
        {
            int len = strValue.Length;
            return len >= this.Minimum && len <= this.Maximum;
        }
        return true;
    }
}

Toutes les propriétés peuvent être définies dans l'attribut comme vous le souhaitez.
Quelques exemples:

[Required]
[StringLengthRange(Minimum = 10, ErrorMessage = "Must be >10 characters.")]

[StringLengthRange(Maximum = 20)]

[Required]
[StringLengthRange(Minimum = 10, Maximum = 20)]

Lorsqu'une propriété particulière n'est pas définie, sa valeur est définie dans le constructeur, elle a donc toujours une valeur. Dans les exemples d'utilisation ci-dessus, j'ai délibérément ajouté le validateur Required, donc il est synchronisé avec ce qui précède attention que j'ai écrit.

Important

Ainsi, ce validateur fonctionnera toujours sur la valeur de votre modèle qui n'est pas requise, mais lorsqu'il est présent, il valide (pensez à un champ de texte dans un formulaire Web, ce n'est pas obligatoire, mais si un utilisateur entre une valeur dans, elle doit être valide) .

88
Robert Koritnik

Utilisez CustomValidationAttribute avec une fonction de validation avec signature

public static ValidationResult Validate(MyType x, ValidationContext context)

Exemple (pour une propriété de chaîne)

using System.ComponentModel.DataAnnotations;

public class MyClass
{
    [CustomValidation(typeof(MyClass), "Validate")]
    public string MyProperty { get; set; }

    public static ValidationResult Validate(string x, ValidationContext context)
    {
        return (x == "valid")
            ? new ValidationResult(null)
            : ValidationResult.Success;
    }
}
4
Micha Wiedenmann