web-dev-qa-db-fra.com

Comment puis-je utiliser des classes d'attributs d'annotations de données pour échouer les chaînes vides dans les formulaires?

J'essayais d'exiger un champ de saisie de texte dans un formulaire, ce qui implique qu'il doit y avoir quelque chose dans le formulaire. Cependant, l'ajout d'un [Required] la balise de mon modèle ne fonctionnait pas. Plus précisément, regardez la propriété Nom d'utilisateur:

public class ColumnWidthMetaData {
    [DisplayName("Column Name")]
    [Required]
    public string ColName { get; set; }

    [DisplayName("Primary Key")]
    public int pKey { get; set; }

    [DisplayName("User Name")]
    [Required]
    public string UserName { get; set; }

    [DisplayName("Column Width")]
    [Required]
    public int Width { get; set; }
}

Cela permet aux chaînes vides d'obtenir la validation du modèle passé et, éventuellement, une erreur de base de données est levée lorsqu'il tente d'insérer une valeur NULL pour le nom d'utilisateur.

Comment puis-je changer ces attributs pour qu'ils fassent ce qu'ils semblent devoir faire?

25
DCShannon

Après beaucoup de recherches sur Google et sur Stackoverflow, je n'avais rien.

Je suis allé sur MSDN et j'ai regardé System.ComponentModel.DataAnnotations Namespace .

Là, j'ai regardé de plus près l'attribut Required et j'ai remarqué la propriété AllowEmptyStrings . La définition de false indique à l'attribut de ne pas autoriser de chaînes vides, ce que j'aurais supposé être le comportement par défaut, vu que le point de Required est d'exiger que quelque chose soit entré, et une chaîne vide indique que rien n'a été entré.

Cela ne résout pas le problème, car par défaut, les chaînes vides sont contraintes à null, qui ne sont pas des chaînes vides, et sont donc autorisées. Encore une fois, c'est absurde, car Required est censé tester si quelque chose a été entré et null indique que rien n'a été entré. Cependant, la page AllowEmptyStrings a un lien vers la propriété de DisplayFormAttributeConvertEmptyStringsToNull . Si vous définissez ce paramètre sur false, les chaînes vides resteront des chaînes vides et la balise requise ne les autorisera pas.

Alors, voici la solution:

public class ColumnWidthMetaData {
    [DisplayName("Column Name")]
    [Required(AllowEmptyStrings=false)]
    [DisplayFormat(ConvertEmptyStringToNull=false)]
    public string ColName { get; set; }

    [DisplayName("Primary Key")]
    public int pKey { get; set; }

    [DisplayName("User Name")]
    [Required(AllowEmptyStrings=false)]
    [DisplayFormat(ConvertEmptyStringToNull=false)]
    public string UserName { get; set; }

    [DisplayName("Column Width")]
    [Required]
    public int Width { get; set; }
}    
63
DCShannon

J'implémenterais un nouvel attribut de validation comme celui-ci et l'appliquerais à mon modèle.

public class RequiredNotEmptyAttribute : RequiredAttribute
{
    public override bool IsValid(object value)
    {
        if(value is string) return String.IsNullOrEmpty((string)value);

        return base.IsValid(value);
    }
}

Cela ne fonctionnera que du côté serveur (le côté client ne vérifiera toujours que null).

5
Nathan A

Vous pouvez ajouter un DefaultValueAttribute à la propriété qui nécessite une valeur par défaut (par exemple, string.Empty pour UserName)

[DisplayName("User Name")]
[System.ComponentModel.DefaultValue("")]
public string UserName { get; set; }
1
quantdev