web-dev-qa-db-fra.com

Messages d'erreur pour la validation de modèle à l'aide d'annotations de données

Étant donné les classes suivantes:

using System.ComponentModel.DataAnnotations;

public class Book{
   public Contact PrimaryContact{get; set;}
   public Contact SecondaryContact{get; set;}

   [Required(ErrorMessage="Book name is required")]
   public string Name{get; set;}
}
public class Contact{
    [Required(ErrorMessage="Name is required")]
    public string Name{get; set;}
}

Existe-t-il un moyen propre de donner un message d'erreur distinct pour chaque instance de Contact dans Book en utilisant DataAnnotations? Par exemple, si le nom manquait dans l'instance PrimaryContact, l'erreur indiquerait "le nom du contact principal est requis". 

Ma solution actuelle consiste à créer un service de validation qui vérifie l'état du modèle à la recherche d'erreurs de champ, puis à supprimer lesdites erreurs et à les rajouter en utilisant le langage spécifique souhaité.

20
IaCoder

C’est le seul moyen que je connaisse, mais c’est loin d’être propre. Cela implique l'utilisation de classes de sous-classes et de métadonnées pour "remplacer" le message d'erreur. 

public class Book
{
    public PrimaryContact PrimaryContact { get; set; }
    public SecondaryContact SecondaryContact { get; set; }

    [Required(ErrorMessage = "Book name is required")]
    public string Name { get; set; }
}

public class Contact
{
    [Required(ErrorMessage = "Name is required")]
    public string Name { get; set; }
}

[MetadataType(typeof(PrimaryContactMD))]
public class PrimaryContact : Contact
{
    class PrimaryContactMD
    {
        [Required(ErrorMessage = "Primary Contact Name is required")]
        public string Name { get; set; }
    }
}

[MetadataType(typeof(SecondaryContactMD))]
public class SecondaryContact : Contact
{
    class SecondaryContactMD
    {
        [Required(ErrorMessage = "Secondary Contact Name is required")]
        public string Name { get; set; }
    }
}
36
Jab

Je comprends que c’est vieux, mais dans l’intérêt d’aider les autres qui rencontrent ce problème et qui trébuchent comme moi, vous voudrez peut-être envisager d’utiliser l’attribut CustomValidation pour de telles propriétés au lieu de vous fier à l’attribut Required.

CustomValidation vous permettra d'adapter plus finement vos messages de validation à la propriété que vous validez. J'ai utilisé context.DisplayName pour afficher de manière dynamique le nom de la propriété en cours de validation, mais ceci peut être personnalisé en fonction de vos besoins.

Si une personnalisation encore plus poussée est nécessaire, vous pouvez écrire différents gestionnaires CustomValidation pour chaque propriété individuelle au lieu de simplement réutiliser le même, comme je l'ai fait dans mon exemple de code.

using System.ComponentModel.DataAnnotations;

public class Book {
    [CustomValidation(typeof(Book), "ValidateContact")]
    public Contact PrimaryContact { get; set; }

    [CustomValidation(typeof(Book), "ValidateContact")]
    public Contact SecondaryContact { get; set; }

    [Required(ErrorMessage = "Book name is required")]
    public string Name { get; set; }

    public static ValidationResult ValidateContact(Contact contact, ValidationContext context) {
        ValidationResult result = null;

        if (contact == null) {
            result = new ValidationResult(string.Format("{0} is required.", context.DisplayName));
        } else if (string.IsNullOrWhiteSpace(contact.Name)) {
            result = new ValidationResult(string.Format("{0} name is required.", context.DisplayName));
        }

        return result;
    }
}

public class Contact {
    [Required(ErrorMessage = "Name is required")]
    public string Name { get; set; }
}
10
synthetik

Je cherche aussi une réponse à ce que j’ai trouvé jusqu’à présent si vous faites quelque chose comme: "{0} Le nom du contact est requis" dans le message d'erreur, le nom de la variable sera automatiquement substitué. Je pense qu'il existe un moyen d'utiliser explicitement cette fonctionnalité.

0
Chris Stephens