asp.net-mvc
Annotations de données
Recherche…
Introduction
Nous pouvons ajouter des validations à notre application en ajoutant des annotations de données à nos classes de modèles. Les annotations de données nous permettent de décrire les règles que nous souhaitons appliquer à nos propriétés de modèle, et ASP.NET MVC se chargera de les appliquer et d'afficher les messages appropriés aux utilisateurs.
Attributs de validation de base utilisés dans ViewModel
Modèle
using System.ComponentModel.DataAnnotations;
public class ViewModel
{
[Required(ErrorMessage="Name is required")]
public string Name { get; set; }
[StringLength(14, MinimumLength = 14, ErrorMessage = "Invalid Phone Number")]
[Required(ErrorMessage="Phone Number is required")]
public string PhoneNo { get; set; }
[Range(typeof(decimal), "0", "150")]
public decimal? Age { get; set; }
[RegularExpression(@"^\d{5}(-\d{4})?$", ErrorMessage = "Invalid Zip Code.")]
public string ZipCode {get;set;}
[EmailAddress(ErrorMessage = "Invalid Email Address")]
public string Email { get; set; }
[Editable(false)]
public string Address{ get; set; }
}
Vue
// Include Jquery and Unobstructive Js here for client side validation
@using (Html.BeginForm("Index","Home") {
@Html.TextBoxFor(model => model.Name)
@Html.ValidationMessageFor(model => model.Name)
@Html.TextBoxFor(model => model.PhoneNo)
@Html.ValidationMessageFor(model => model.PhoneNo)
@Html.TextBoxFor(model => model.Age)
@Html.ValidationMessageFor(model => model.Age)
@Html.TextBoxFor(model => model.ZipCode)
@Html.ValidationMessageFor(model => model.ZipCode)
@Html.TextBoxFor(model => model.Email)
@Html.ValidationMessageFor(model => model.Email)
@Html.TextBoxFor(model => model.Address)
@Html.ValidationMessageFor(model => model.Address)
<input type="submit" value="submit" />
}
Manette
public ActionResult Index(ViewModel _Model)
{
// Checking whether the Form posted is valid one.
if(ModelState.IsValid)
{
// your model is valid here.
// perform any actions you need to, like database actions,
// and/or redirecting to other controllers and actions.
}
else
{
// redirect to same action
return View(_Model);
}
}
Validation à distance
La validation à distance utilisée pour vérifier si le contenu entre dans le contrôle d'entrée est valide ou non en envoyant une requête ajax au serveur pour le vérifier.
Travail
RemoteAttribute
fonctionne en effectuant un appel AJAX du client vers une action de contrôleur avec la valeur du champ en cours de validation. L'action du contrôleur renvoie ensuite une réponse JsonResult
indiquant le succès ou l'échec de la validation. Retourner true
de votre action indique que la validation a réussi. Toute autre valeur indique un échec. Si vous retournez false
, le message d'erreur spécifié dans l'attribut est utilisé. Si vous retournez autre chose, par exemple une chaîne ou même un entier, le message d'erreur apparaîtra. Sauf si vous avez besoin que votre message d'erreur soit dynamique, il est logique de renvoyer true ou false et de laisser le validateur utiliser le message d'erreur spécifié sur l'attribut.
ViewModel
public class ViewModel
{
[Remote("IsEmailAvailable", "Group", HttpMethod = "POST", ErrorMessage = "Email already exists. Please enter a different email address.")]
public string Email{ get; set; }
}
Manette
[HttpPost]
public JsonResult IsEmailAvailable(string Email)
{
// Logic to check whether email is already registered or Not.
var emailExists = IsEmailRegistered();
return Json(!emailExists);
}
Vous pouvez transmettre des propriétés supplémentaires du modèle à la méthode du contrôleur à l'aide de la propriété AdditionalFields
de RemoteAttribute
. Un scénario typique consisterait à transmettre la propriété ID du modèle dans un formulaire «Modifier», afin que la logique du contrôleur puisse ignorer les valeurs de l'enregistrement existant.
Modèle
public int? ID { get; set; }
[Display(Name = "Email address")]
[DataType(DataType.EmailAddress)]
[Required(ErrorMessage = "Please enter you email address")]
[Remote("IsEmailAvailable", HttpMethod="Post", AdditionalFields="ID", ErrorMessage = "Email already exists. Please enter a different email address.")]
public string Email { get; set; }
Manette
[HttpPost]
public ActionResult Validate(string email, int? id)
{
if (id.HasValue)
{
return Json(!db.Users.Any(x => x.Email == email && x.ID != id);
}
else
{
return Json(!db.Users.Any(x => x.Email == email);
}
}
Démo de travail - Champs supplémentaires
Note supplémentaire
Le message d'erreur par défaut est naturellement vague, n'oubliez donc pas de remplacer le message d'erreur par défaut lorsque vous utilisez RemoteAttribute
.
RequiredAttribute
L'attribut Required
spécifie qu'une propriété est requise. Un message d'erreur peut être spécifié en utilisant la propriété ErrorMessage
sur l'attribut.
Ajoutez d'abord l'espace de nom:
using System.ComponentModel.DataAnnotations;
Et appliquer l'attribut sur une propriété.
public class Product
{
[Required(ErrorMessage = "The product name is required.")]
public string Name { get; set; }
[Required(ErrorMessage = "The product description is required.")]
public string Description { get; set; }
}
Il est également possible d'utiliser des ressources dans le message d'erreur pour les applications globalisées. Dans ce cas, le ErrorMessageResourceName
doit être spécifiée avec la clé des ressources de la classe de ressources ( resx
de fichier) qui doit être paramétré sur le ErrorMessageResourceType
:
public class Product
{
[Required(ErrorMessageResourceName = "ProductNameRequired",
ErrorMessageResourceType = typeof(ResourceClass))]
public string Name { get; set; }
[Required(ErrorMessageResourceName = "ProductDescriptionRequired",
ErrorMessageResourceType = typeof(ResourceClass))]
public string Description { get; set; }
}
StringLengthAttribute
L'attribut StringLength
spécifie la longueur minimale et maximale des caractères autorisés dans un champ de données. Cet attribut peut être appliqué aux propriétés, aux champs publics et aux paramètres. Le message d'erreur doit être spécifié sur la propriété ErrorMessage
de l'attribut. Les propriétés MinimumLength
et MaximumLength
spécifient respectivement le minimum et le maximum.
Ajoutez d'abord l'espace de nom:
using System.ComponentModel.DataAnnotations;
Et appliquer l'attribut sur une propriété.
public class User
{
// set the maximum
[StringLength(20, ErrorMessage = "The username cannot exceed 20 characters. ")]
public string Username { get; set; }
[StringLength(MinimumLength = 3, MaximumLength = 16, ErrorMessage = "The password must have between 3 and 16 characters.")]
public string Password { get; set; }
}
Il est également possible d'utiliser des ressources dans le message d'erreur pour les applications globalisées. Dans ce cas, le ErrorMessageResourceName
doit être spécifiée avec la clé des ressources de la classe de ressources ( resx
de fichier) qui doit être paramétré sur le ErrorMessageResourceType
:
public class User
{
[StringLength(20, ErrorMessageResourceName = "StringLength",
ErrorMessageResourceType = typeof(ResoucesKeys))]
public string Username { get; set; }
[StringLength(MinimumLength = 3,
MaximumLength = 16,
ErrorMessageResourceName = "StringLength",
ErrorMessageResourceType = typeof(ResoucesKeys))]
public string Password { get; set; }
}
Attribut de plage
L'attribut Range
peut décorer des propriétés ou des champs publics et spécifie une plage entre laquelle un champ numérique doit figurer pour être considéré comme valide.
[Range(minimumValue, maximumValue)]
public int Property { get; set; }
En outre, il accepte une propriété ErrorMessage
facultative qui peut être utilisée pour définir le message reçu par l'utilisateur lorsque des données non valides sont entrées:
[Range(minimumValue, maximumValue, ErrorMessage = "{your-error-message}")]
public int Property { get; set; }
Exemple
[Range(1,100, ErrorMessage = "Ranking must be between 1 and 100.")]
public int Ranking { get; set; }
Attribut RegularExpression
L'attribut [RegularExpression]
peut décorer des propriétés ou des champs publics et spécifie une expression régulière qui doit correspondre pour que la propriété soit considérée comme valide.
[RegularExpression(validationExpression)]
public string Property { get; set; }
En outre, il accepte une propriété ErrorMessage
facultative qui peut être utilisée pour définir le message reçu par l'utilisateur lorsque des données non valides sont entrées:
[RegularExpression(validationExpression, ErrorMessage = "{your-error-message}")]
public string Property { get; set; }
Exemples)
[RegularExpression(@"^[a-z]{8,16}?$", ErrorMessage = "A User Name must consist of 8-16 lowercase letters")]
public string UserName{ get; set; }
[RegularExpression(@"^\d{5}(-\d{4})?$", ErrorMessage = "Please enter a valid ZIP Code (e.g. 12345, 12345-1234)")]
public string ZipCode { get; set; }
Comparer l'attribut
L'attribut Compare
compare deux propriétés d'un modèle.
Le message d'erreur peut être spécifié en utilisant la propriété ErrorMessage
ou en utilisant des fichiers de ressources.
Pour utiliser l'attribut Compare
devez using
pour l'espace de noms suivant:
using System.ComponentModel.DataAnnotations;
Ensuite, vous pouvez utiliser l'attribut dans votre modèle:
public class RegisterModel
{
public string Email { get; set; }
[Compare("Email", ErrorMessage = "The Email and Confirm Email fields do not match.")]
public string ConfirmEmail { get; set; }
}
Lorsque ce modèle est validé, si les valeurs Email
et ConfirmEmail
sont différentes, la validation échouera.
Messages d'erreur localisés
Tout comme avec tous les attributs de validation, il est possible d'utiliser des messages d'erreur provenant de fichiers de ressources. Dans cet exemple, le message d'erreur sera chargé à partir du fichier de ressources Resources
, le nom de la ressource est CompareValidationMessage
:
public class RegisterModel
{
public string Email { get; set; }
["Email", ErrorMessageResourceType = typeof(Resources), ErrorMessageResourceName = "CompareValidationMessage")]
public string ConfirmEmail { get; set; }
}
Eviter les chaînes dans les noms de propriétés
Pour éviter d'utiliser la chaîne pour la valeur de la propriété, dans C # 6+, vous pouvez utiliser nameof
mot-clé:
public class RegisterModel
{
public string Email { get; set; }
[Compare(nameof(Email), ErrorMessage = "The Email and Confirm Email fields do not match.")]
public string ConfirmEmail { get; set; }
}
Placeholders dans les messages d'erreur
Vous pouvez utiliser des espaces réservés dans vos messages d'erreur. L'espace réservé {0}
est remplacé par le nom complet de la propriété en cours et {1}
est remplacé par le nom d'affichage de la propriété associée:
public class RegisterModel
{
[Display(Name = "Email")]
public string Email { get; set; }
[Display(Name = "Confirm Email")]
[Compare("Email", ErrorMessage = "The '{1}' and '{0}' fields do not match.")]
public string ConfirmEmail { get; set; }
}
Si la validation du modèle échoue, le message d'erreur sera
Les champs 'Email' et 'Confirm Email' ne correspondent pas.
Attribut de validation personnalisé
Lorsqu'il s'agit de valider certaines règles qui ne sont pas des validations de données génériques, par exemple en vous assurant qu'un champ est requis ou une plage de valeurs, mais qu'elles sont spécifiques à votre logique métier, vous pouvez créer votre propre validateur personnalisé . Pour créer un attribut de validation personnalisé, il vous suffit d' inherit
classe ValidationAttribute
et de override
sa méthode IsValid
. La méthode IsValid
prend deux paramètres, le premier est un object
nommé en tant que value
et le second est un ValidationContext object
nommé en tant que validationContext
. Value
fait référence à la valeur réelle du champ que votre validateur personnalisé va valider.
Supposons que vous souhaitiez valider un Email
via un Custom Validator
public class MyCustomValidator : ValidationAttribute
{
private static string myEmail= "[email protected]";
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
string Email = value.ToString();
if(myEmail.Equals(Email))
return new ValidationResult("Email Already Exist");
return ValidationResult.Success;
}
}
public class SampleViewModel
{
[MyCustomValidator]
[Required]
public string Email { get; set; }
public string Name { get; set; }
}
Voici sa démo DotNetFiddle
Modèle EDMx - Annotation des données
Edmx modèle internel
public partial class ItemRequest
{
public int RequestId { get; set; }
//...
}
Ajouter des annotations de données à cela - si nous modifions directement ce modèle, lorsqu'une mise à jour du modèle est effectuée, les modifications sont perdues. alors
Pour ajouter un attribut dans ce cas, 'Obligatoire'
Créez une nouvelle classe - n'importe quel nom
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
//make sure the namespace is equal to the other partial class ItemRequest
namespace MvcApplication1.Models
{
[MetadataType(typeof(ItemRequestMetaData))]
public partial class ItemRequest
{
}
public class ItemRequestMetaData
{
[Required]
public int RequestId {get;set;}
//...
}
}
ou
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace YourApplication.Models
{
public interface IEntityMetadata
{
[Required]
Int32 Id { get; set; }
}
[MetadataType(typeof(IEntityMetadata))]
public partial class Entity : IEntityMetadata
{
/* Id property has already existed in the mapped class */
}
}
Annotations de données pour la première implémentation de la base de données (code de modèle généré automatiquement)
[MetadataType(typeof(RoleMetaData))]
public partial class ROLE
{
}
public class RoleMetaData
{
[Display(Name = "Role")]
public string ROLE_DESCRIPTION { get; set; }
[Display(Name = "Username")]
public string ROLE_USERNAME { get; set; }
}
Si vous avez utilisé database-first et que votre code de modèle a été généré automatiquement, ce message apparaîtra au-dessus de votre code de modèle:
Ce code a été généré à partir d'un modèle. Les modifications manuelles apportées à ce fichier peuvent entraîner un comportement inattendu dans votre application. Les modifications manuelles apportées à ce fichier seront remplacées si le code est régénéré
Si vous souhaitez utiliser des annotations de données et que vous ne voulez pas qu'elles soient écrasées si vous actualisez edmx, ajoutez simplement une autre classe partielle à votre dossier de modèle qui ressemble à l'exemple ci-dessus.