Partie 8 de la série de tutoriels sur Pages Razor

Remarque

Ceci n’est pas la dernière version de cet article. Pour la version actuelle, consultez la version .NET 8 de cet article.

Important

Ces informations portent sur la préversion du produit, qui est susceptible d’être en grande partie modifié avant sa commercialisation. Microsoft n’offre aucune garantie, expresse ou implicite, concernant les informations fournies ici.

Pour la version actuelle, consultez la version .NET 8 de cet article.

Par Rick Anderson

Dans cette section, une logique de validation est ajoutée au modèle Movie. Les règles de validation sont appliquées chaque fois qu’un utilisateur crée ou modifie un film.

Validation

DRYDon't Repeat Yourself », Ne vous répétez pas) constitue un principe clé du développement de logiciel. Les Pages Razor favorisent le développement dans lequel une fonctionnalité est spécifiée une seule fois et sont répercutées dans toute l’application. DRY peut aider à :

  • Réduire la quantité de code dans une application.
  • Rendre le code moins sujet aux erreurs, et plus facile à tester et à maintenir.

La prise en charge de la validation fournie par les Pages Razor et Entity Framework est un bon exemple du principe DRY :

  • Les règles de validation sont spécifiées de manière déclarative au même endroit, dans la classe de modèle.
  • Les règles sont appliquées partout dans l’application.

Ajouter des règles de validation au modèle de film

L’espace de nom System.ComponentModel.DataAnnotations fournit :

  • Ensemble d’attributs de validation intégrés appliqués de manière déclarative à une classe ou à une propriété.
  • Attributs de mise en forme comme [DataType] qui aident à effectuer la mise en forme et ne fournissent aucune validation.

Mettez à jour la classe Movie pour tirer parti des attributs de validation intégrés [Required], [StringLength], [RegularExpression] et [Range].

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace RazorPagesMovie.Models;

public class Movie
{
    public int Id { get; set; }

    [StringLength(60, MinimumLength = 3)]
    [Required]
    public string Title { get; set; } = string.Empty;

    [DataType(DataType.Date)]
    public DateTime ReleaseDate { get; set; }

    [Range(1, 100)]
    [DataType(DataType.Currency)]
    [Column(TypeName = "decimal(18, 2)")]
    public decimal Price { get; set; }

    [RegularExpression(@"^[A-Z]+[a-zA-Z\s]*$")]
    [Required]
    [StringLength(30)]
    public string Genre { get; set; } = string.Empty;

    [RegularExpression(@"^[A-Z]+[a-zA-Z0-9""'\s-]*$")]
    [StringLength(5)]
    [Required]
    public string Rating { get; set; } = string.Empty;
}

Les attributs de validation spécifient le comportement à appliquer sur les propriétés du modèle auxquelles ils sont appliqués :

  • Les attributs [Required] et [MinimumLength] indiquent qu’une propriété doit avoir une valeur. Rien n’empêche un utilisateur d’entrer des espaces blancs pour satisfaire cette validation.

  • L’attribut [RegularExpression] sert à limiter les caractères pouvant être entrés. Dans le code précédent, Genre :

    • Doit utiliser seulement des lettres.
    • La première lettre doit être une majuscule. Les espaces sont autorisés, tandis que les nombres et les caractères spéciaux ne le sont pas.
  • RegularExpressionRating :

    • Nécessite que le premier caractère soit une lettre majuscule.
    • Autorise les caractères spéciaux et les chiffres aux emplacements qui suivent. « PG-13 » est valide pour une évaluation, mais échoue pour un Genre.
  • L’attribut [Range] limite une valeur à une plage spécifiée.

  • L’attribut [StringLength] peut définir la longueur maximale d’une propriété de chaîne, et éventuellement sa longueur minimale.

  • Les types valeur (tels que decimal, int, float, DateTime) sont obligatoires par nature et n’ont pas besoin de l’attribut [Required].

Les règles de validation précédentes sont utilisées pour la démonstration, elles ne sont pas optimales pour un système de production. Par exemple, le précédent empêche d’entrer un film avec seulement deux caractères et n’autorise pas les caractères spéciaux dans Genre.

L’application automatique des règles de validation par ASP.NET Core permet de :

  • Rendre l’application plus robuste.
  • Réduire les risques d’enregistrement de données non valides dans la base de données.

Interface utilisateur d’erreur de validation dans les Pages Razor

Exécutez l’application, puis accédez à Pages/Movies.

Sélectionnez le lien Créer nouveau. Complétez le formulaire avec des valeurs non valides. Quand la validation jQuery côté client détecte l’erreur, elle affiche un message d’erreur.

Formulaire de vue Movie avec plusieurs erreurs de validation jQuery côté client

Notes

Vous ne pourrez peut-être pas entrer de virgules décimales dans les champs décimaux. Pour prendre en charge la validation jQuery pour les paramètres régionaux autres que l’anglais qui utilisent une virgule (« , ») comme décimale et des formats de date autres que l’anglais des États-Unis, vous devez effectuer des étapes pour localiser votre application. Consultez ce commentaire GitHub 4076 pour savoir comment ajouter une virgule décimale.

Notez que le formulaire a affiché automatiquement un message d’erreur de validation dans chaque champ contenant une valeur non valide. Les erreurs sont appliquées à la fois côté client à l’aide de JavaScript et de jQuery, et côté serveur quand JavaScript est désactivé pour un utilisateur.

L’un des principaux avantages est qu’aucun changement de code n’a été nécessaire dans les pages Créer ou Modifier. Une fois les annotations de données appliquées au modèle, l’interface utilisateur de validation a été activée. Les Pages Movie créées dans ce tutoriel ont prélevé les règles de validation à l’aide des attributs de validation définis sur les propriétés de la classe de modèle Razor. Testez la validation à l’aide de la page de modification. La même validation est appliquée.

Les données de formulaire ne sont pas publiées sur le serveur tant qu’il y a des erreurs de validation côté client. Vérifiez que les données du formulaire ne sont pas publiées à l’aide d’une ou de plusieurs des approches suivantes :

  • Placez un point d’arrêt dans la méthode OnPostAsync. Envoyez le formulaire en sélectionnant Créer ou Enregistrer. Le point d’arrêt n’est jamais atteint.
  • Utilisez l’outil Fiddler.
  • Utilisez les outils de développement du navigateur pour surveiller le trafic réseau.

Validation côté serveur

Quand JavaScript est désactivé dans le navigateur, l’envoi du formulaire avec des erreurs poste les données sur le serveur.

Facultatif : Testez la validation côté serveur :

  1. Désactivez JavaScript dans le navigateur. JavaScript peut être désactivé à l’aide des outils de développement du navigateur. Si JavaScript ne peut pas être désactivé dans le navigateur, essayez un autre navigateur.

  2. Définissez un point d’arrêt dans la méthode OnPostAsync de la page Créer ou Modifier.

  3. Envoyez un formulaire avec des données non valides.

  4. Vérifiez que l’état de modèle n’est pas valide :

     if (!ModelState.IsValid)
     {
        return Page();
     }
    

Vous pouvez également désactiver la validation côté client sur le serveur.

Le code suivant affiche la partie de la page Create.cshtml générée automatiquement plus tôt dans le tutoriel. Elle est utilisée par les pages Créer et Modifier pour :

  • Affichez le formulaire initial.
  • Réafficher le formulaire en cas d’erreur.
<form method="post">
    <div asp-validation-summary="ModelOnly" class="text-danger"></div>
    <div class="form-group">
        <label asp-for="Movie.Title" class="control-label"></label>
        <input asp-for="Movie.Title" class="form-control" />
        <span asp-validation-for="Movie.Title" class="text-danger"></span>
    </div>

Le Tag Helper d’entrée utilise les attributs DataAnnotations et produit les attributs HTML nécessaires à la validation jQuery côté client. Le Tag Helper Validation affiche les erreurs de validation. Pour plus d’informations, consultez Validation.

Les pages Créer et Modifier ne contiennent pas de règles de validation. Les règles de validation et les chaînes d’erreur sont spécifiées uniquement dans la classe Movie. Ces règles de validation sont automatiquement appliquées aux pages Razorqui modifient le modèle Movie.

Quand la logique de validation doit être modifiée, cela s’effectue uniquement dans le modèle. La validation est appliquée de manière cohérente dans l’ensemble de l’application. La logique de validation est définie dans un emplacement unique. La validation dans un emplacement unique permet de maintenir votre code clair, et d’en faciliter la maintenance et la mise à jour.

Utiliser des attributs DataType

Examiner la classe Movie. L’espace de noms System.ComponentModel.DataAnnotations fournit des attributs de mise en forme en plus de l’ensemble intégré d’attributs de validation. L’attribut [DataType] est appliqué aux propriétés ReleaseDate et Price.

[DataType(DataType.Date)]
public DateTime ReleaseDate { get; set; }

[Range(1, 100)]
[DataType(DataType.Currency)]
[Column(TypeName = "decimal(18, 2)")]
public decimal Price { get; set; }

Les attributs [DataType] fournissent :

  • Conseils pour le moteur d’affichage pour mettre en forme les données.
  • Fournit des attributs tels que <a> pour l’URL et <a href="mailto:EmailAddress.com"> pour l’e-mail.

Utilisez l’attribut [RegularExpression] pour valider le format des données. L’attribut [DataType] sert à spécifier un type de données qui est plus spécifique que le type intrinsèque de la base de données. Les attributs [DataType] ne sont pas des attributs de validation. Dans l’échantillon d’application, seule la date est affichée, sans l’heure.

L’énumération DataType fournit de nombreux types de données, tels que Date, Time, PhoneNumber, Currency, EmailAddress, et bien plus encore.

Les attributs [DataType] :

  • Peut permettre à l’application de fournir automatiquement des fonctionnalités propres au type. Par exemple, il est possible de créer un lien mailto: pour DataType.EmailAddress.
  • Peuvent fournir un sélecteur de date DataType.Date dans les navigateurs qui prennent en charge HTML5.
  • Émettent HTML 5 data-, prononcé « tiret de données », attributs utilisés par les navigateurs HTML 5.
  • Ne fournissent aucune validation.

DataType.Date ne spécifie pas le format de la date qui s’affiche. Par défaut, le champ de données est affiché conformément aux formats par défaut basés sur le CultureInfo du serveur.

L’annotation de données [Column(TypeName = "decimal(18, 2)")] est nécessaire pour qu’Entity Framework Core puisse correctement mapper Price en devise dans la base de données. Pour plus d’informations, consultez Types de données.

L’attribut [DisplayFormat] est utilisé pour spécifier explicitement le format de date :

[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime ReleaseDate { get; set; }

Le paramètre ApplyFormatInEditMode indique que la mise en forme sera appliquée quand la valeur est affichée à des fins de modification. Ce comportement n’est peut-être pas souhaité pour certains champs. Par exemple, dans les valeurs monétaires, le symbole monétaire n’est généralement pas voulu dans l’interface utilisateur de modification.

L’attribut [DisplayFormat] peut être utilisé seul, mais il est généralement préférable d’utiliser l’attribut [DataType]. L’attribut [DataType] transmet la sémantique des données, plutôt que la manière de l’afficher à l’écran. L’attribut [DataType] offre les avantages suivants qui ne sont pas disponibles avec [DisplayFormat] :

  • Le navigateur peut activer des fonctionnalités HTML5, par exemple pour afficher un contrôle de calendrier, le symbole monétaire correspondant aux paramètres régionaux, des liens de messagerie, etc.
  • Par défaut, le navigateur affiche les données à l’aide du format correspondant aux paramètres régionaux.
  • L’attribut [DataType] peut permettre à l’infrastructure ASP.NET Core de choisir le modèle de champ approprié pour afficher les données. S’il est utilisé seul, DisplayFormat utilise le modèle de chaîne.

Remarque : La validation jQuery ne fonctionne pas avec l’attribut [Range] et DateTime. Par exemple, le code suivant affiche toujours une erreur de validation côté client, même quand la date se trouve dans la plage spécifiée :

[Range(typeof(DateTime), "1/1/1966", "1/1/2020")]

Il recommandé d’éviter de compiler des dates en dur dans des modèles. Par conséquent, l’utilisation de l’attribut [Range] et de DateTime est déconseillée. Utilisez Configuration pour les plages de dates et d’autres valeurs qui sont sujettes à des modifications fréquentes au lieu de les spécifier dans le code.

Le code suivant illustre la combinaison d’attributs sur une seule ligne :

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace RazorPagesMovie.Models;

public class Movie
{
    public int Id { get; set; }

    [StringLength(60, MinimumLength = 3)]
    public string Title { get; set; } = string.Empty;

    [Display(Name = "Release Date"), DataType(DataType.Date)]
    public DateTime ReleaseDate { get; set; }

    [RegularExpression(@"^[A-Z]+[a-zA-Z\s]*$"), Required, StringLength(30)]
    public string Genre { get; set; } = string.Empty;

    [Range(1, 100), DataType(DataType.Currency)]
    [Column(TypeName = "decimal(18, 2)")]
    public decimal Price { get; set; }

    [RegularExpression(@"^[A-Z]+[a-zA-Z0-9""'\s-]*$"), StringLength(5)]
    public string Rating { get; set; } = string.Empty;
}

Prise en main des Pages Razor et EF Core affiche les opérations avancées EF Core avec Pages Razor.

Appliquer des migrations

L’application de DataAnnotations à la classe modifie le schéma. Par exemple, DataAnnotations appliqué au champ Title :

[StringLength(60, MinimumLength = 3)]
[Required]
public string Title { get; set; } = string.Empty;
  • limite les caractères à 60 ;
  • n’autorise pas de valeur null.

La table Movie a actuellement le schéma suivant :

CREATE TABLE [dbo].[Movie] (
    [ID]          INT             IDENTITY (1, 1) NOT NULL,
    [Title]       NVARCHAR (MAX)  NULL,
    [ReleaseDate] DATETIME2 (7)   NOT NULL,
    [Genre]       NVARCHAR (MAX)  NULL,
    [Price]       DECIMAL (18, 2) NOT NULL,
    [Rating]      NVARCHAR (MAX)  NULL,
    CONSTRAINT [PK_Movie] PRIMARY KEY CLUSTERED ([ID] ASC)
);

Les modifications précédentes du schéma n’entraînent pas la levée d’une exception par EF. Cependant, créez une migration pour que le schéma soit cohérent avec le modèle.

Dans le menu Outils, sélectionnez Gestionnaire de package NuGet > Console du gestionnaire de package. Dans la console du gestionnaire de package, entrez les commandes suivantes :

Add-Migration New_DataAnnotations
Update-Database

Update-Database exécute la méthode Up de la classe New_DataAnnotations.

Examinez la méthode Up :

public partial class New_DataAnnotations : Migration
{
    /// <inheritdoc />
    protected override void Up(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.AlterColumn<string>(
            name: "Title",
            table: "Movie",
            type: "nvarchar(60)",
            maxLength: 60,
            nullable: false,
            oldClrType: typeof(string),
            oldType: "nvarchar(max)");

        migrationBuilder.AlterColumn<string>(
            name: "Rating",
            table: "Movie",
            type: "nvarchar(5)",
            maxLength: 5,
            nullable: false,
            oldClrType: typeof(string),
            oldType: "nvarchar(max)");

        migrationBuilder.AlterColumn<string>(
            name: "Genre",
            table: "Movie",
            type: "nvarchar(30)",
            maxLength: 30,
            nullable: false,
            oldClrType: typeof(string),
            oldType: "nvarchar(max)");
    }

La table Movie mise à jour a le schéma suivant :

CREATE TABLE [dbo].[Movie] (
    [ID]          INT             IDENTITY (1, 1) NOT NULL,
    [Title]       NVARCHAR (60)   NOT NULL,
    [ReleaseDate] DATETIME2 (7)   NOT NULL,
    [Genre]       NVARCHAR (30)   NOT NULL,
    [Price]       DECIMAL (18, 2) NOT NULL,
    [Rating]      NVARCHAR (5)    NOT NULL,
    CONSTRAINT [PK_Movie] PRIMARY KEY CLUSTERED ([ID] ASC)
);

Publication dans Azure

Pour plus d’informations sur le déploiement sur Azure, consultez Tutoriel : Créer une application ASP.NET Core dans Azure avec SQL Database.

Nous vous remercions d’avoir effectué cette introduction aux pages Razor. Pour compléter ce tutoriel, vous pouvez consulter Bien démarrer avec les Pages Razor et EF Core.

Ressources supplémentaires

Étapes suivantes

Dans cette section, une logique de validation est ajoutée au modèle Movie. Les règles de validation sont appliquées chaque fois qu’un utilisateur crée ou modifie un film.

Validation

DRYDon't Repeat Yourself », Ne vous répétez pas) constitue un principe clé du développement de logiciel. Les Pages Razor favorisent le développement dans lequel une fonctionnalité est spécifiée une seule fois et sont répercutées dans toute l’application. DRY peut aider à :

  • Réduire la quantité de code dans une application.
  • Rendre le code moins sujet aux erreurs, et plus facile à tester et à maintenir.

La prise en charge de la validation fournie par les Pages Razor et Entity Framework est un bon exemple du principe DRY :

  • Les règles de validation sont spécifiées de manière déclarative au même endroit, dans la classe de modèle.
  • Les règles sont appliquées partout dans l’application.

Ajouter des règles de validation au modèle de film

L’espace de nom System.ComponentModel.DataAnnotations fournit :

  • Ensemble d’attributs de validation intégrés appliqués de manière déclarative à une classe ou à une propriété.
  • Attributs de mise en forme comme [DataType] qui aident à effectuer la mise en forme et ne fournissent aucune validation.

Mettez à jour la classe Movie pour tirer parti des attributs de validation intégrés [Required], [StringLength], [RegularExpression] et [Range].

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace RazorPagesMovie.Models;

public class Movie
{
    public int Id { get; set; }

    [StringLength(60, MinimumLength = 3)]
    [Required]
    public string Title { get; set; } = string.Empty;

    // [Display(Name = "Release Date")]
    [DataType(DataType.Date)]
    public DateTime ReleaseDate { get; set; }

    [Range(1, 100)]
    [DataType(DataType.Currency)]
    [Column(TypeName = "decimal(18, 2)")]
    public decimal Price { get; set; }

    [RegularExpression(@"^[A-Z]+[a-zA-Z\s]*$")]
    [Required]
    [StringLength(30)]
    public string Genre { get; set; } = string.Empty;

    [RegularExpression(@"^[A-Z]+[a-zA-Z0-9""'\s-]*$")]
    [StringLength(5)]
    [Required]
    public string Rating { get; set; } = string.Empty;
}

Les attributs de validation spécifient le comportement à appliquer sur les propriétés du modèle auxquelles ils sont appliqués :

  • Les attributs [Required] et [MinimumLength] indiquent qu’une propriété doit avoir une valeur. Rien n’empêche un utilisateur d’entrer des espaces blancs pour satisfaire cette validation.

  • L’attribut [RegularExpression] sert à limiter les caractères pouvant être entrés. Dans le code précédent, Genre :

    • Doit utiliser seulement des lettres.
    • La première lettre doit être une majuscule. Les espaces blancs sont autorisés tandis que les nombres et les caractères spéciaux ne sont pas autorisés.
  • RegularExpressionRating :

    • Nécessite que le premier caractère soit une lettre majuscule.
    • Autorise les caractères spéciaux et les chiffres aux emplacements qui suivent. « PG-13 » est valide pour une évaluation, mais échoue pour un Genre.
  • L’attribut [Range] limite une valeur à une plage spécifiée.

  • L’attribut [StringLength] peut définir la longueur maximale d’une propriété de chaîne, et éventuellement sa longueur minimale.

  • Les types valeur (tels que decimal, int, float, DateTime) sont obligatoires par nature et n’ont pas besoin de l’attribut [Required].

Les règles de validation précédentes sont utilisées pour la démonstration, elles ne sont pas optimales pour un système de production. Par exemple, le précédent empêche d’entrer un film avec seulement deux caractères et n’autorise pas les caractères spéciaux dans Genre.

L’application automatique des règles de validation par ASP.NET Core permet de :

  • Rendre l’application plus robuste.
  • Réduire les risques d’enregistrement de données non valides dans la base de données.

Interface utilisateur d’erreur de validation dans les Pages Razor

Exécutez l’application, puis accédez à Pages/Movies.

Sélectionnez le lien Créer nouveau. Complétez le formulaire avec des valeurs non valides. Quand la validation jQuery côté client détecte l’erreur, elle affiche un message d’erreur.

Formulaire de vue Movie avec plusieurs erreurs de validation jQuery côté client

Notes

Vous ne pourrez peut-être pas entrer de virgules décimales dans les champs décimaux. Pour prendre en charge la validation jQuery pour les paramètres régionaux autres que l’anglais qui utilisent une virgule (« , ») comme décimale et des formats de date autres que l’anglais des États-Unis, vous devez effectuer des étapes pour localiser votre application. Consultez ce commentaire GitHub 4076 pour savoir comment ajouter une virgule décimale.

Notez que le formulaire a affiché automatiquement un message d’erreur de validation dans chaque champ contenant une valeur non valide. Les erreurs sont appliquées à la fois côté client à l’aide de JavaScript et de jQuery, et côté serveur quand JavaScript est désactivé pour un utilisateur.

L’un des principaux avantages est qu’aucun changement de code n’a été nécessaire dans les pages Créer ou Modifier. Une fois les annotations de données appliquées au modèle, l’interface utilisateur de validation a été activée. Les Pages Movie créées dans ce tutoriel ont prélevé les règles de validation à l’aide des attributs de validation définis sur les propriétés de la classe de modèle Razor. Testez la validation à l’aide de la page de modification. La même validation est appliquée.

Les données de formulaire ne sont pas publiées sur le serveur tant qu’il y a des erreurs de validation côté client. Vérifiez que les données du formulaire ne sont pas publiées à l’aide d’une ou de plusieurs des approches suivantes :

  • Placez un point d’arrêt dans la méthode OnPostAsync. Envoyez le formulaire en sélectionnant Créer ou Enregistrer. Le point d’arrêt n’est jamais atteint.
  • Utilisez l’outil Fiddler.
  • Utilisez les outils de développement du navigateur pour surveiller le trafic réseau.

Validation côté serveur

Quand JavaScript est désactivé dans le navigateur, l’envoi du formulaire avec des erreurs poste les données sur le serveur.

Facultatif : Testez la validation côté serveur :

  1. Désactivez JavaScript dans le navigateur. JavaScript peut être désactivé à l’aide des outils de développement du navigateur. Si JavaScript ne peut pas être désactivé dans le navigateur, essayez un autre navigateur.

  2. Définissez un point d’arrêt dans la méthode OnPostAsync de la page Créer ou Modifier.

  3. Envoyez un formulaire avec des données non valides.

  4. Vérifiez que l’état de modèle n’est pas valide :

     if (!ModelState.IsValid)
     {
        return Page();
     }
    

Vous pouvez également désactiver la validation côté client sur le serveur.

Le code suivant affiche la partie de la page Create.cshtml générée automatiquement plus tôt dans le tutoriel. Elle est utilisée par les pages Créer et Modifier pour :

  • Affichez le formulaire initial.
  • Réafficher le formulaire en cas d’erreur.
<form method="post">
    <div asp-validation-summary="ModelOnly" class="text-danger"></div>
    <div class="form-group">
        <label asp-for="Movie.Title" class="control-label"></label>
        <input asp-for="Movie.Title" class="form-control" />
        <span asp-validation-for="Movie.Title" class="text-danger"></span>
    </div>

Le Tag Helper d’entrée utilise les attributs DataAnnotations et produit les attributs HTML nécessaires à la validation jQuery côté client. Le Tag Helper Validation affiche les erreurs de validation. Pour plus d’informations, consultez Validation.

Les pages Créer et Modifier ne contiennent pas de règles de validation. Les règles de validation et les chaînes d’erreur sont spécifiées uniquement dans la classe Movie. Ces règles de validation sont automatiquement appliquées aux pages Razorqui modifient le modèle Movie.

Quand la logique de validation doit être modifiée, cela s’effectue uniquement dans le modèle. La validation est appliquée de manière cohérente dans l’ensemble de l’application. La logique de validation est définie dans un emplacement unique. La validation dans un emplacement unique permet de maintenir votre code clair, et d’en faciliter la maintenance et la mise à jour.

Utiliser des attributs DataType

Examiner la classe Movie. L’espace de noms System.ComponentModel.DataAnnotations fournit des attributs de mise en forme en plus de l’ensemble intégré d’attributs de validation. L’attribut [DataType] est appliqué aux propriétés ReleaseDate et Price.

// [Display(Name = "Release Date")]
[DataType(DataType.Date)]
public DateTime ReleaseDate { get; set; }

[Range(1, 100)]
[DataType(DataType.Currency)]
[Column(TypeName = "decimal(18, 2)")]
public decimal Price { get; set; }

Les attributs [DataType] fournissent :

  • Conseils pour le moteur d’affichage pour mettre en forme les données.
  • Fournit des attributs tels que <a> pour l’URL et <a href="mailto:EmailAddress.com"> pour l’e-mail.

Utilisez l’attribut [RegularExpression] pour valider le format des données. L’attribut [DataType] sert à spécifier un type de données qui est plus spécifique que le type intrinsèque de la base de données. Les attributs [DataType] ne sont pas des attributs de validation. Dans l’échantillon d’application, seule la date est affichée, sans l’heure.

L’énumération DataType fournit de nombreux types de données, tels que Date, Time, PhoneNumber, Currency, EmailAddress, et bien plus encore.

Les attributs [DataType] :

  • Peut permettre à l’application de fournir automatiquement des fonctionnalités propres au type. Par exemple, il est possible de créer un lien mailto: pour DataType.EmailAddress.
  • Peuvent fournir un sélecteur de date DataType.Date dans les navigateurs qui prennent en charge HTML5.
  • Émettent HTML 5 data-, prononcé « tiret de données », attributs utilisés par les navigateurs HTML 5.
  • Ne fournissent aucune validation.

DataType.Date ne spécifie pas le format de la date qui s’affiche. Par défaut, le champ de données est affiché conformément aux formats par défaut basés sur le CultureInfo du serveur.

L’annotation de données [Column(TypeName = "decimal(18, 2)")] est nécessaire pour qu’Entity Framework Core puisse correctement mapper Price en devise dans la base de données. Pour plus d’informations, consultez Types de données.

L’attribut [DisplayFormat] est utilisé pour spécifier explicitement le format de date :

[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime ReleaseDate { get; set; }

Le paramètre ApplyFormatInEditMode indique que la mise en forme sera appliquée quand la valeur est affichée à des fins de modification. Ce comportement n’est peut-être pas souhaité pour certains champs. Par exemple, dans les valeurs monétaires, le symbole monétaire n’est généralement pas voulu dans l’interface utilisateur de modification.

L’attribut [DisplayFormat] peut être utilisé seul, mais il est généralement préférable d’utiliser l’attribut [DataType]. L’attribut [DataType] transmet la sémantique des données, plutôt que la manière de l’afficher à l’écran. L’attribut [DataType] offre les avantages suivants qui ne sont pas disponibles avec [DisplayFormat] :

  • Le navigateur peut activer des fonctionnalités HTML5, par exemple pour afficher un contrôle de calendrier, le symbole monétaire correspondant aux paramètres régionaux, des liens de messagerie, etc.
  • Par défaut, le navigateur affiche les données à l’aide du format correspondant aux paramètres régionaux.
  • L’attribut [DataType] peut permettre à l’infrastructure ASP.NET Core de choisir le modèle de champ approprié pour afficher les données. S’il est utilisé seul, DisplayFormat utilise le modèle de chaîne.

Remarque : La validation jQuery ne fonctionne pas avec l’attribut [Range] et DateTime. Par exemple, le code suivant affiche toujours une erreur de validation côté client, même quand la date se trouve dans la plage spécifiée :

[Range(typeof(DateTime), "1/1/1966", "1/1/2020")]

Il recommandé d’éviter de compiler des dates en dur dans des modèles. Par conséquent, l’utilisation de l’attribut [Range] et de DateTime est déconseillée. Utilisez Configuration pour les plages de dates et d’autres valeurs qui sont sujettes à des modifications fréquentes au lieu de les spécifier dans le code.

Le code suivant illustre la combinaison d’attributs sur une seule ligne :

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace RazorPagesMovie.Models;

public class Movie
{
    public int Id { get; set; }

    [StringLength(60, MinimumLength = 3)]
    public string Title { get; set; } = string.Empty;

    [Display(Name = "Release Date"), DataType(DataType.Date)]
    public DateTime ReleaseDate { get; set; }

    [RegularExpression(@"^[A-Z]+[a-zA-Z\s]*$"), Required, StringLength(30)]
    public string Genre { get; set; } = string.Empty;

    [Range(1, 100), DataType(DataType.Currency)]
    [Column(TypeName = "decimal(18, 2)")]
    public decimal Price { get; set; }

    [RegularExpression(@"^[A-Z]+[a-zA-Z0-9""'\s-]*$"), StringLength(5)]
    public string Rating { get; set; } = string.Empty;
}

Prise en main des Pages Razor et EF Core affiche les opérations avancées EF Core avec Pages Razor.

Appliquer des migrations

L’application de DataAnnotations à la classe modifie le schéma. Par exemple, DataAnnotations appliqué au champ Title :

[StringLength(60, MinimumLength = 3)]
[Required]
public string Title { get; set; } = string.Empty;
  • limite les caractères à 60 ;
  • n’autorise pas de valeur null.

La table Movie a actuellement le schéma suivant :

CREATE TABLE [dbo].[Movie] (
    [ID]          INT             IDENTITY (1, 1) NOT NULL,
    [Title]       NVARCHAR (MAX)  NULL,
    [ReleaseDate] DATETIME2 (7)   NOT NULL,
    [Genre]       NVARCHAR (MAX)  NULL,
    [Price]       DECIMAL (18, 2) NOT NULL,
    [Rating]      NVARCHAR (MAX)  NULL,
    CONSTRAINT [PK_Movie] PRIMARY KEY CLUSTERED ([ID] ASC)
);

Les modifications précédentes du schéma n’entraînent pas la levée d’une exception par EF. Cependant, créez une migration pour que le schéma soit cohérent avec le modèle.

Dans le menu Outils, sélectionnez Gestionnaire de package NuGet > Console du gestionnaire de package. Dans la console du gestionnaire de package, entrez les commandes suivantes :

Add-Migration New_DataAnnotations
Update-Database

Update-Database exécute la méthode Up de la classe New_DataAnnotations.

Examinez la méthode Up :

public partial class NewDataAnnotations : Migration
{
    /// <inheritdoc />
    protected override void Up(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.AlterColumn<string>(
            name: "Title",
            table: "Movie",
            type: "nvarchar(60)",
            maxLength: 60,
            nullable: false,
            oldClrType: typeof(string),
            oldType: "nvarchar(max)");

        migrationBuilder.AlterColumn<string>(
            name: "Rating",
            table: "Movie",
            type: "nvarchar(5)",
            maxLength: 5,
            nullable: false,
            oldClrType: typeof(string),
            oldType: "nvarchar(max)");

        migrationBuilder.AlterColumn<string>(
            name: "Genre",
            table: "Movie",
            type: "nvarchar(30)",
            maxLength: 30,
            nullable: false,
            oldClrType: typeof(string),
            oldType: "nvarchar(max)");
    }

La table Movie mise à jour a le schéma suivant :

CREATE TABLE [dbo].[Movie] (
    [ID]          INT             IDENTITY (1, 1) NOT NULL,
    [Title]       NVARCHAR (60)   NOT NULL,
    [ReleaseDate] DATETIME2 (7)   NOT NULL,
    [Genre]       NVARCHAR (30)   NOT NULL,
    [Price]       DECIMAL (18, 2) NOT NULL,
    [Rating]      NVARCHAR (5)    NOT NULL,
    CONSTRAINT [PK_Movie] PRIMARY KEY CLUSTERED ([ID] ASC)
);

Publication dans Azure

Pour plus d’informations sur le déploiement sur Azure, consultez Tutoriel : Créer une application ASP.NET Core dans Azure avec SQL Database.

Nous vous remercions d’avoir effectué cette introduction aux pages Razor. Pour compléter ce tutoriel, vous pouvez consulter Bien démarrer avec les Pages Razor et EF Core.

Ressources supplémentaires

Étapes suivantes

Dans cette section, une logique de validation est ajoutée au modèle Movie. Les règles de validation sont appliquées chaque fois qu’un utilisateur crée ou modifie un film.

Validation

DRYDon't Repeat Yourself », Ne vous répétez pas) constitue un principe clé du développement de logiciel. Les Pages Razor favorisent le développement dans lequel une fonctionnalité est spécifiée une seule fois et sont répercutées dans toute l’application. DRY peut aider à :

  • Réduire la quantité de code dans une application.
  • Rendre le code moins sujet aux erreurs, et plus facile à tester et à maintenir.

La prise en charge de la validation fournie par les Pages Razor et Entity Framework est un bon exemple du principe DRY :

  • Les règles de validation sont spécifiées de manière déclarative au même endroit, dans la classe de modèle.
  • Les règles sont appliquées partout dans l’application.

Ajouter des règles de validation au modèle de film

L’espace de nom System.ComponentModel.DataAnnotations fournit :

  • Ensemble d’attributs de validation intégrés appliqués de manière déclarative à une classe ou à une propriété.
  • Attributs de mise en forme comme [DataType] qui aident à effectuer la mise en forme et ne fournissent aucune validation.

Mettez à jour la classe Movie pour tirer parti des attributs de validation intégrés [Required], [StringLength], [RegularExpression] et [Range].

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace RazorPagesMovie.Models
{
    public class Movie
    {
        public int ID { get; set; }

        [StringLength(60, MinimumLength = 3)]
        [Required]
        public string Title { get; set; } = string.Empty;

        [Display(Name = "Release Date")]
        [DataType(DataType.Date)]
        public DateTime ReleaseDate { get; set; }

        [Range(1, 100)]
        [DataType(DataType.Currency)]
        [Column(TypeName = "decimal(18, 2)")]
        public decimal Price { get; set; }

        [RegularExpression(@"^[A-Z]+[a-zA-Z\s]*$")]
        [Required]
        [StringLength(30)]
        public string Genre { get; set; } = string.Empty;

        [RegularExpression(@"^[A-Z]+[a-zA-Z0-9""'\s-]*$")]
        [StringLength(5)]
        [Required]
        public string Rating { get; set; } = string.Empty;
    }
}

Les attributs de validation spécifient le comportement à appliquer sur les propriétés du modèle auxquelles ils sont appliqués :

  • Les attributs [Required] et [MinimumLength] indiquent qu’une propriété doit avoir une valeur. Rien n’empêche un utilisateur d’entrer des espaces blancs pour satisfaire cette validation.

  • L’attribut [RegularExpression] sert à limiter les caractères pouvant être entrés. Dans le code précédent, Genre :

    • Doit utiliser seulement des lettres.
    • La première lettre doit être une majuscule. Les espaces blancs sont autorisés tandis que les nombres et les caractères spéciaux ne sont pas autorisés.
  • RegularExpressionRating :

    • Nécessite que le premier caractère soit une lettre majuscule.
    • Autorise les caractères spéciaux et les chiffres aux emplacements qui suivent. « PG-13 » est valide pour une évaluation, mais échoue pour un Genre.
  • L’attribut [Range] limite une valeur à une plage spécifiée.

  • L’attribut [StringLength] peut définir la longueur maximale d’une propriété de chaîne, et éventuellement sa longueur minimale.

  • Les types valeur (tels que decimal, int, float, DateTime) sont obligatoires par nature et n’ont pas besoin de l’attribut [Required].

Les règles de validation précédentes sont utilisées pour la démonstration, elles ne sont pas optimales pour un système de production. Par exemple, le précédent empêche d’entrer un film avec seulement deux caractères et n’autorise pas les caractères spéciaux dans Genre.

L’application automatique des règles de validation par ASP.NET Core permet de :

  • Rendre l’application plus robuste.
  • Réduire les risques d’enregistrement de données non valides dans la base de données.

Interface utilisateur d’erreur de validation dans les Pages Razor

Exécutez l’application, puis accédez à Pages/Movies.

Sélectionnez le lien Créer nouveau. Complétez le formulaire avec des valeurs non valides. Quand la validation jQuery côté client détecte l’erreur, elle affiche un message d’erreur.

Formulaire de vue Movie avec plusieurs erreurs de validation jQuery côté client

Notes

Vous ne pourrez peut-être pas entrer de virgules décimales dans les champs décimaux. Pour prendre en charge la validation jQuery pour les paramètres régionaux autres que l’anglais qui utilisent une virgule (« , ») comme décimale et des formats de date autres que l’anglais des États-Unis, vous devez effectuer des étapes pour localiser votre application. Consultez ce commentaire GitHub 4076 pour savoir comment ajouter une virgule décimale.

Notez que le formulaire a affiché automatiquement un message d’erreur de validation dans chaque champ contenant une valeur non valide. Les erreurs sont appliquées à la fois côté client à l’aide de JavaScript et de jQuery, et côté serveur quand JavaScript est désactivé pour un utilisateur.

L’un des principaux avantages est qu’aucun changement de code n’a été nécessaire dans les pages Créer ou Modifier. Une fois les annotations de données appliquées au modèle, l’interface utilisateur de validation a été activée. Les Pages Movie créées dans ce tutoriel ont prélevé les règles de validation à l’aide des attributs de validation définis sur les propriétés de la classe de modèle Razor. Testez la validation à l’aide de la page de modification. La même validation est appliquée.

Les données de formulaire ne sont pas publiées sur le serveur tant qu’il y a des erreurs de validation côté client. Vérifiez que les données du formulaire ne sont pas publiées à l’aide d’une ou de plusieurs des approches suivantes :

  • Placez un point d’arrêt dans la méthode OnPostAsync. Envoyez le formulaire en sélectionnant Créer ou Enregistrer. Le point d’arrêt n’est jamais atteint.
  • Utilisez l’outil Fiddler.
  • Utilisez les outils de développement du navigateur pour surveiller le trafic réseau.

Validation côté serveur

Quand JavaScript est désactivé dans le navigateur, l’envoi du formulaire avec des erreurs poste les données sur le serveur.

Facultatif : Testez la validation côté serveur :

  1. Désactivez JavaScript dans le navigateur. JavaScript peut être désactivé à l’aide des outils de développement du navigateur. Si vous ne pouvez pas désactiver JavaScript dans le navigateur, essayez un autre navigateur.

  2. Définissez un point d’arrêt dans la méthode OnPostAsync de la page Créer ou Modifier.

  3. Envoyez un formulaire avec des données non valides.

  4. Vérifiez que l’état de modèle n’est pas valide :

     if (!ModelState.IsValid)
     {
        return Page();
     }
    

Vous pouvez également désactiver la validation côté client sur le serveur.

Le code suivant affiche la partie de la page Create.cshtml générée automatiquement plus tôt dans le tutoriel. Elle est utilisée par les pages Créer et Modifier pour :

  • Affichez le formulaire initial.
  • Réafficher le formulaire en cas d’erreur.
<form method="post">
    <div asp-validation-summary="ModelOnly" class="text-danger"></div>
    <div class="form-group">
        <label asp-for="Movie.Title" class="control-label"></label>
        <input asp-for="Movie.Title" class="form-control" />
        <span asp-validation-for="Movie.Title" class="text-danger"></span>
    </div>

Le Tag Helper d’entrée utilise les attributs DataAnnotations et produit les attributs HTML nécessaires à la validation jQuery côté client. Le Tag Helper Validation affiche les erreurs de validation. Pour plus d’informations, consultez Validation.

Les pages Créer et Modifier ne contiennent pas de règles de validation. Les règles de validation et les chaînes d’erreur sont spécifiées uniquement dans la classe Movie. Ces règles de validation sont automatiquement appliquées aux pages Razorqui modifient le modèle Movie.

Quand la logique de validation doit être modifiée, cela s’effectue uniquement dans le modèle. La validation est appliquée de manière cohérente dans l’ensemble de l’application, la logique de validation est définie dans un emplacement unique. La validation dans un emplacement unique permet de maintenir votre code clair, et d’en faciliter la maintenance et la mise à jour.

Utiliser des attributs DataType

Examiner la classe Movie. L’espace de noms System.ComponentModel.DataAnnotations fournit des attributs de mise en forme en plus de l’ensemble intégré d’attributs de validation. L’attribut [DataType] est appliqué aux propriétés ReleaseDate et Price.

[Display(Name = "Release Date")]
[DataType(DataType.Date)]
public DateTime ReleaseDate { get; set; }

[Range(1, 100)]
[DataType(DataType.Currency)]
[Column(TypeName = "decimal(18, 2)")]
public decimal Price { get; set; }

Les attributs [DataType] fournissent :

  • Conseils pour le moteur d’affichage pour mettre en forme les données.
  • Fournit des attributs tels que <a> pour l’URL et <a href="mailto:EmailAddress.com"> pour l’e-mail.

Utilisez l’attribut [RegularExpression] pour valider le format des données. L’attribut [DataType] sert à spécifier un type de données qui est plus spécifique que le type intrinsèque de la base de données. Les attributs [DataType] ne sont pas des attributs de validation. Dans l’exemple d’application, seule la date est affichée, sans l’heure.

L’énumération DataType fournit de nombreux types de données, tels que Date, Time, PhoneNumber, Currency, EmailAddress, et bien plus encore.

Les attributs [DataType] :

  • Peut permettre à l’application de fournir automatiquement des fonctionnalités propres au type. Par exemple, il est possible de créer un lien mailto: pour DataType.EmailAddress.
  • Peuvent fournir un sélecteur de date DataType.Date dans les navigateurs qui prennent en charge HTML5.
  • Émettent HTML 5 data-, prononcé « tiret de données », attributs utilisés par les navigateurs HTML 5.
  • Ne fournissent aucune validation.

DataType.Date ne spécifie pas le format de la date qui s’affiche. Par défaut, le champ de données est affiché conformément aux formats par défaut basés sur le CultureInfo du serveur.

L’annotation de données [Column(TypeName = "decimal(18, 2)")] est nécessaire pour qu’Entity Framework Core puisse correctement mapper Price en devise dans la base de données. Pour plus d’informations, consultez Types de données.

L’attribut [DisplayFormat] est utilisé pour spécifier explicitement le format de date :

[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime ReleaseDate { get; set; }

Le paramètre ApplyFormatInEditMode indique que la mise en forme sera appliquée quand la valeur est affichée à des fins de modification. Ce comportement n’est peut-être pas souhaité pour certains champs. Par exemple, dans les valeurs monétaires, le symbole monétaire n’est généralement pas voulu dans l’interface utilisateur de modification.

L’attribut [DisplayFormat] peut être utilisé seul, mais il est généralement préférable d’utiliser l’attribut [DataType]. L’attribut [DataType] transmet la sémantique des données, plutôt que la manière de l’afficher à l’écran. L’attribut [DataType] offre les avantages suivants qui ne sont pas disponibles avec [DisplayFormat] :

  • Le navigateur peut activer des fonctionnalités HTML5, par exemple pour afficher un contrôle de calendrier, le symbole monétaire correspondant aux paramètres régionaux, des liens de messagerie, etc.
  • Par défaut, le navigateur affiche les données à l’aide du format correspondant aux paramètres régionaux.
  • L’attribut [DataType] peut permettre à l’infrastructure ASP.NET Core de choisir le modèle de champ approprié pour afficher les données. S’il est utilisé seul, DisplayFormat utilise le modèle de chaîne.

Remarque : La validation jQuery ne fonctionne pas avec l’attribut [Range] et DateTime. Par exemple, le code suivant affiche toujours une erreur de validation côté client, même quand la date se trouve dans la plage spécifiée :

[Range(typeof(DateTime), "1/1/1966", "1/1/2020")]

Il recommandé d’éviter de compiler des dates en dur dans des modèles. Par conséquent, l’utilisation de l’attribut [Range] et de DateTime est déconseillée. Utilisez Configuration pour les plages de dates et d’autres valeurs qui sont sujettes à des modifications fréquentes au lieu de les spécifier dans le code.

Le code suivant illustre la combinaison d’attributs sur une seule ligne :

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace RazorPagesMovie.Models
{
    public class Movie
    {
        public int ID { get; set; }

        [StringLength(60, MinimumLength = 3)]
        public string Title { get; set; } = string.Empty;

        [Display(Name = "Release Date"), DataType(DataType.Date)]
        public DateTime ReleaseDate { get; set; }

        [RegularExpression(@"^[A-Z]+[a-zA-Z\s]*$"), Required, StringLength(30)]
        public string Genre { get; set; } = string.Empty;

        [Range(1, 100), DataType(DataType.Currency)]
        [Column(TypeName = "decimal(18, 2)")]
        public decimal Price { get; set; }

        [RegularExpression(@"^[A-Z]+[a-zA-Z0-9""'\s-]*$"), StringLength(5)]
        public string Rating { get; set; } = string.Empty;
    }
}

Prise en main des Pages Razor et EF Core affiche les opérations avancées EF Core avec Pages Razor.

Appliquer des migrations

L’application de DataAnnotations à la classe modifie le schéma. Par exemple, DataAnnotations appliqué au champ Title :

[StringLength(60, MinimumLength = 3)]
[Required]
public string Title { get; set; } = string.Empty;
  • limite les caractères à 60 ;
  • n’autorise pas de valeur null.

La table Movie a actuellement le schéma suivant :

CREATE TABLE [dbo].[Movie] (
    [ID]          INT             IDENTITY (1, 1) NOT NULL,
    [Title]       NVARCHAR (MAX)  NULL,
    [ReleaseDate] DATETIME2 (7)   NOT NULL,
    [Genre]       NVARCHAR (MAX)  NULL,
    [Price]       DECIMAL (18, 2) NOT NULL,
    [Rating]      NVARCHAR (MAX)  NULL,
    CONSTRAINT [PK_Movie] PRIMARY KEY CLUSTERED ([ID] ASC)
);

Les modifications précédentes du schéma n’entraînent pas la levée d’une exception par EF. Cependant, créez une migration pour que le schéma soit cohérent avec le modèle.

Dans le menu Outils, sélectionnez Gestionnaire de package NuGet > Console du gestionnaire de package. Dans la console du gestionnaire de package, entrez les commandes suivantes :

Add-Migration New_DataAnnotations
Update-Database

Update-Database exécute la méthode Up de la classe New_DataAnnotations.

Examinez la méthode Up :

public partial class New_DataAnnotations : Migration
{
    protected override void Up(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.AlterColumn<string>(
            name: "Title",
            table: "Movie",
            type: "nvarchar(60)",
            maxLength: 60,
            nullable: false,
            oldClrType: typeof(string),
            oldType: "nvarchar(max)");

        migrationBuilder.AlterColumn<string>(
            name: "Rating",
            table: "Movie",
            type: "nvarchar(5)",
            maxLength: 5,
            nullable: false,
            oldClrType: typeof(string),
            oldType: "nvarchar(max)");

        migrationBuilder.AlterColumn<string>(
            name: "Genre",
            table: "Movie",
            type: "nvarchar(30)",
            maxLength: 30,
            nullable: false,
            oldClrType: typeof(string),
            oldType: "nvarchar(max)");
    }

La table Movie mise à jour a le schéma suivant :

CREATE TABLE [dbo].[Movie] (
    [ID]          INT             IDENTITY (1, 1) NOT NULL,
    [Title]       NVARCHAR (60)   NOT NULL,
    [ReleaseDate] DATETIME2 (7)   NOT NULL,
    [Genre]       NVARCHAR (30)   NOT NULL,
    [Price]       DECIMAL (18, 2) NOT NULL,
    [Rating]      NVARCHAR (5)    NOT NULL,
    CONSTRAINT [PK_Movie] PRIMARY KEY CLUSTERED ([ID] ASC)
);

Publication dans Azure

Pour plus d’informations sur le déploiement sur Azure, consultez Tutoriel : Créer une application ASP.NET Core dans Azure avec SQL Database.

Nous vous remercions d’avoir effectué cette introduction aux pages Razor. Pour compléter ce tutoriel, vous pouvez consulter Bien démarrer avec les Pages Razor et EF Core.

Ressources supplémentaires

Étapes suivantes

Dans cette section, une logique de validation est ajoutée au modèle Movie. Les règles de validation sont appliquées chaque fois qu’un utilisateur crée ou modifie un film.

Validation

DRYDon't Repeat Yourself », Ne vous répétez pas) constitue un principe clé du développement de logiciel. Les Pages Razor favorisent le développement dans lequel une fonctionnalité est spécifiée une seule fois et sont répercutées dans toute l’application. DRY peut aider à :

  • Réduire la quantité de code dans une application.
  • Rendre le code moins sujet aux erreurs, et plus facile à tester et à maintenir.

La prise en charge de la validation fournie par les Pages Razor et Entity Framework est un bon exemple du principe DRY :

  • Les règles de validation sont spécifiées de manière déclarative au même endroit, dans la classe de modèle.
  • Les règles sont appliquées partout dans l’application.

Ajouter des règles de validation au modèle de film

L’espace de nom DataAnnotations fournit :

  • Ensemble d’attributs de validation intégrés appliqués de manière déclarative à une classe ou à une propriété.
  • Attributs de mise en forme comme [DataType] qui aident à effectuer la mise en forme et ne fournissent aucune validation.

Mettez à jour la classe Movie pour tirer parti des attributs de validation intégrés [Required], [StringLength], [RegularExpression] et [Range].

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace RazorPagesMovie.Models
{
    public class Movie
    {
        public int ID { get; set; }

        [StringLength(60, MinimumLength = 3)]
        [Required]
        public string Title { get; set; }

        [Display(Name = "Release Date")]
        [DataType(DataType.Date)]
        public DateTime ReleaseDate { get; set; }

        [Range(1, 100)]
        [DataType(DataType.Currency)]
        [Column(TypeName = "decimal(18, 2)")]
        public decimal Price { get; set; }

        [RegularExpression(@"^[A-Z]+[a-zA-Z\s]*$")]
        [Required]
        [StringLength(30)]
        public string Genre { get; set; }

        [RegularExpression(@"^[A-Z]+[a-zA-Z0-9""'\s-]*$")]
        [StringLength(5)]
        [Required]
        public string Rating { get; set; }
    }
}

Les attributs de validation spécifient le comportement à appliquer sur les propriétés du modèle auxquelles ils sont appliqués :

  • Les attributs [Required] et [MinimumLength] indiquent qu’une propriété doit avoir une valeur. Rien n’empêche un utilisateur d’entrer des espaces blancs pour satisfaire cette validation.

  • L’attribut [RegularExpression] sert à limiter les caractères pouvant être entrés. Dans le code précédent, Genre :

    • Doit utiliser seulement des lettres.
    • La première lettre doit être une majuscule. Les espaces blancs sont autorisés tandis que les nombres et les caractères spéciaux ne sont pas autorisés.
  • RegularExpressionRating :

    • Nécessite que le premier caractère soit une lettre majuscule.
    • Autorise les caractères spéciaux et les chiffres aux emplacements qui suivent. « PG-13 » est valide pour une évaluation, mais échoue pour un Genre.
  • L’attribut [Range] limite une valeur à une plage spécifiée.

  • L’attribut [StringLength] peut définir la longueur maximale d’une propriété de chaîne, et éventuellement sa longueur minimale.

  • Les types valeur (tels que decimal, int, float, DateTime) sont obligatoires par nature et n’ont pas besoin de l’attribut [Required].

Les règles de validation précédentes sont utilisées pour la démonstration, elles ne sont pas optimales pour un système de production. Par exemple, le précédent empêche d’entrer un film avec seulement deux caractères et n’autorise pas les caractères spéciaux dans Genre.

L’application automatique des règles de validation par ASP.NET Core permet de :

  • Rendre l’application plus robuste.
  • Réduire les risques d’enregistrement de données non valides dans la base de données.

Interface utilisateur d’erreur de validation dans les Pages Razor

Exécutez l’application, puis accédez à Pages/Movies.

Sélectionnez le lien Créer nouveau. Complétez le formulaire avec des valeurs non valides. Quand la validation jQuery côté client détecte l’erreur, elle affiche un message d’erreur.

Formulaire de vue Movie avec plusieurs erreurs de validation jQuery côté client

Notes

Vous ne pourrez peut-être pas entrer de virgules décimales dans les champs décimaux. Pour prendre en charge la validation jQuery pour les paramètres régionaux autres que l’anglais qui utilisent une virgule (« , ») comme décimale et des formats de date autres que l’anglais des États-Unis, vous devez effectuer des étapes pour localiser votre application. Consultez ce commentaire GitHub 4076 pour savoir comment ajouter une virgule décimale.

Notez que le formulaire a affiché automatiquement un message d’erreur de validation dans chaque champ contenant une valeur non valide. Les erreurs sont appliquées à la fois côté client à l’aide de JavaScript et de jQuery, et côté serveur quand JavaScript est désactivé pour un utilisateur.

L’un des principaux avantages est qu’aucun changement de code n’a été nécessaire dans les pages Créer ou Modifier. Une fois les annotations de données appliquées au modèle, l’interface utilisateur de validation a été activée. Les Pages Movie créées dans ce tutoriel ont prélevé les règles de validation à l’aide des attributs de validation définis sur les propriétés de la classe de modèle Razor. Testez la validation à l’aide de la page de modification. La même validation est appliquée.

Les données de formulaire ne sont pas publiées sur le serveur tant qu’il y a des erreurs de validation côté client. Vérifiez que les données du formulaire ne sont pas publiées à l’aide d’une ou de plusieurs des approches suivantes :

  • Placez un point d’arrêt dans la méthode OnPostAsync. Envoyez le formulaire en sélectionnant Créer ou Enregistrer. Le point d’arrêt n’est jamais atteint.
  • Utilisez l’outil Fiddler.
  • Utilisez les outils de développement du navigateur pour surveiller le trafic réseau.

Validation côté serveur

Quand JavaScript est désactivé dans le navigateur, l’envoi du formulaire avec des erreurs poste les données sur le serveur.

Facultatif : Testez la validation côté serveur :

  1. Désactivez JavaScript dans le navigateur. JavaScript peut être désactivé à l’aide des outils de développement du navigateur. Si JavaScript ne peut pas être désactivé dans le navigateur, essayez un autre navigateur.

  2. Définissez un point d’arrêt dans la méthode OnPostAsync de la page Créer ou Modifier.

  3. Envoyez un formulaire avec des données non valides.

  4. Vérifiez que l’état de modèle n’est pas valide :

     if (!ModelState.IsValid)
     {
        return Page();
     }
    

Vous pouvez également désactiver la validation côté client sur le serveur.

Le code suivant affiche la partie de la page Create.cshtml générée automatiquement plus tôt dans le tutoriel. Elle est utilisée par les pages Créer et Modifier pour :

  • Affichez le formulaire initial.
  • Réafficher le formulaire en cas d’erreur.
<form method="post">
    <div asp-validation-summary="ModelOnly" class="text-danger"></div>
    <div class="form-group">
        <label asp-for="Movie.Title" class="control-label"></label>
        <input asp-for="Movie.Title" class="form-control" />
        <span asp-validation-for="Movie.Title" class="text-danger"></span>
    </div>

Le Tag Helper d’entrée utilise les attributs DataAnnotations et produit les attributs HTML nécessaires à la validation jQuery côté client. Le Tag Helper Validation affiche les erreurs de validation. Pour plus d’informations, consultez Validation.

Les pages Créer et Modifier ne contiennent pas de règles de validation. Les règles de validation et les chaînes d’erreur sont spécifiées uniquement dans la classe Movie. Ces règles de validation sont automatiquement appliquées aux pages Razorqui modifient le modèle Movie.

Quand la logique de validation doit être modifiée, cela s’effectue uniquement dans le modèle. La validation est appliquée de manière cohérente dans l’ensemble de l’application, la logique de validation est définie dans un emplacement unique. La validation dans un emplacement unique permet de maintenir votre code clair, et d’en faciliter la maintenance et la mise à jour.

Utiliser des attributs DataType

Examiner la classe Movie. L’espace de noms System.ComponentModel.DataAnnotations fournit des attributs de mise en forme en plus de l’ensemble intégré d’attributs de validation. L’attribut [DataType] est appliqué aux propriétés ReleaseDate et Price.

[Display(Name = "Release Date")]
[DataType(DataType.Date)]
public DateTime ReleaseDate { get; set; }

[Range(1, 100)]
[DataType(DataType.Currency)]
public decimal Price { get; set; }

Les attributs [DataType] fournissent :

  • Conseils pour le moteur d’affichage pour mettre en forme les données.
  • Fournit des attributs tels que <a> pour l’URL et <a href="mailto:EmailAddress.com"> pour l’e-mail.

Utilisez l’attribut [RegularExpression] pour valider le format des données. L’attribut [DataType] sert à spécifier un type de données qui est plus spécifique que le type intrinsèque de la base de données. Les attributs [DataType] ne sont pas des attributs de validation. Dans l’exemple d’application, seule la date est affichée, sans l’heure.

L’énumération DataType fournit de nombreux types de données, tels que Date, Time, PhoneNumber, Currency, EmailAddress, et bien plus encore.

Les attributs [DataType] :

  • Peut permettre à l’application de fournir automatiquement des fonctionnalités propres au type. Par exemple, il est possible de créer un lien mailto: pour DataType.EmailAddress.
  • Peuvent fournir un sélecteur de date DataType.Date dans les navigateurs qui prennent en charge HTML5.
  • Émettent HTML 5 data-, prononcé « tiret de données », attributs utilisés par les navigateurs HTML 5.
  • Ne fournissent aucune validation.

DataType.Date ne spécifie pas le format de la date qui s’affiche. Par défaut, le champ de données est affiché conformément aux formats par défaut basés sur le CultureInfo du serveur.

L’annotation de données [Column(TypeName = "decimal(18, 2)")] est nécessaire pour qu’Entity Framework Core puisse correctement mapper Price en devise dans la base de données. Pour plus d’informations, consultez Types de données.

L’attribut [DisplayFormat] est utilisé pour spécifier explicitement le format de date :

[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime ReleaseDate { get; set; }

Le paramètre ApplyFormatInEditMode indique que la mise en forme sera appliquée quand la valeur est affichée à des fins de modification. Ce comportement n’est peut-être pas souhaité pour certains champs. Par exemple, dans les valeurs monétaires, le symbole monétaire n’est généralement pas voulu dans l’interface utilisateur de modification.

L’attribut [DisplayFormat] peut être utilisé seul, mais il est généralement préférable d’utiliser l’attribut [DataType]. L’attribut [DataType] transmet la sémantique des données, plutôt que la manière de l’afficher à l’écran. L’attribut [DataType] offre les avantages suivants qui ne sont pas disponibles avec [DisplayFormat] :

  • Le navigateur peut activer des fonctionnalités HTML5, par exemple pour afficher un contrôle de calendrier, le symbole monétaire correspondant aux paramètres régionaux, des liens de messagerie, etc.
  • Par défaut, le navigateur affiche les données à l’aide du format correspondant aux paramètres régionaux.
  • L’attribut [DataType] peut permettre à l’infrastructure ASP.NET Core de choisir le modèle de champ approprié pour afficher les données. S’il est utilisé seul, DisplayFormat utilise le modèle de chaîne.

Remarque : La validation jQuery ne fonctionne pas avec l’attribut [Range] et DateTime. Par exemple, le code suivant affiche toujours une erreur de validation côté client, même quand la date se trouve dans la plage spécifiée :

[Range(typeof(DateTime), "1/1/1966", "1/1/2020")]

Il recommandé d’éviter de compiler des dates en dur dans des modèles. Par conséquent, l’utilisation de l’attribut [Range] et de DateTime est déconseillée. Utilisez Configuration pour les plages de dates et d’autres valeurs qui sont sujettes à des modifications fréquentes au lieu de les spécifier dans le code.

Le code suivant illustre la combinaison d’attributs sur une seule ligne :

public class Movie
{
    public int ID { get; set; }

    [StringLength(60, MinimumLength = 3)]
    public string Title { get; set; }

    [Display(Name = "Release Date"), DataType(DataType.Date)]
    public DateTime ReleaseDate { get; set; }

    [RegularExpression(@"^[A-Z]+[a-zA-Z\s]*$"), Required, StringLength(30)]
    public string Genre { get; set; }

    [Range(1, 100), DataType(DataType.Currency)]
    [Column(TypeName = "decimal(18, 2)")]
    public decimal Price { get; set; }

    [RegularExpression(@"^[A-Z]+[a-zA-Z0-9""'\s-]*$"), StringLength(5)]
    public string Rating { get; set; }
}

Prise en main des Pages Razor et EF Core affiche les opérations avancées EF Core avec Pages Razor.

Appliquer des migrations

L’application de DataAnnotations à la classe modifie le schéma. Par exemple, DataAnnotations appliqué au champ Title :

[StringLength(60, MinimumLength = 3)]
[Required]
public string Title { get; set; }
  • limite les caractères à 60 ;
  • n’autorise pas de valeur null.

La table Movie a actuellement le schéma suivant :

CREATE TABLE [dbo].[Movie] (
    [ID]          INT             IDENTITY (1, 1) NOT NULL,
    [Title]       NVARCHAR (MAX)  NULL,
    [ReleaseDate] DATETIME2 (7)   NOT NULL,
    [Genre]       NVARCHAR (MAX)  NULL,
    [Price]       DECIMAL (18, 2) NOT NULL,
    [Rating]      NVARCHAR (MAX)  NULL,
    CONSTRAINT [PK_Movie] PRIMARY KEY CLUSTERED ([ID] ASC)
);

Les modifications précédentes du schéma n’entraînent pas la levée d’une exception par EF. Cependant, créez une migration pour que le schéma soit cohérent avec le modèle.

Dans le menu Outils, sélectionnez Gestionnaire de package NuGet > Console du gestionnaire de package. Dans la console du gestionnaire de package, entrez les commandes suivantes :

Add-Migration New_DataAnnotations
Update-Database

Update-Database exécute les méthodes Up de la classe New_DataAnnotations. Examinez la méthode Up :

public partial class New_DataAnnotations : Migration
{
    protected override void Up(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.AlterColumn<string>(
            name: "Title",
            table: "Movie",
            maxLength: 60,
            nullable: false,
            oldClrType: typeof(string),
            oldNullable: true);

        migrationBuilder.AlterColumn<string>(
            name: "Rating",
            table: "Movie",
            maxLength: 5,
            nullable: false,
            oldClrType: typeof(string),
            oldNullable: true);

        migrationBuilder.AlterColumn<string>(
            name: "Genre",
            table: "Movie",
            maxLength: 30,
            nullable: false,
            oldClrType: typeof(string),
            oldNullable: true);
    }

La table Movie mise à jour a le schéma suivant :

CREATE TABLE [dbo].[Movie] (
    [ID]          INT             IDENTITY (1, 1) NOT NULL,
    [Title]       NVARCHAR (60)   NOT NULL,
    [ReleaseDate] DATETIME2 (7)   NOT NULL,
    [Genre]       NVARCHAR (30)   NOT NULL,
    [Price]       DECIMAL (18, 2) NOT NULL,
    [Rating]      NVARCHAR (5)    NOT NULL,
    CONSTRAINT [PK_Movie] PRIMARY KEY CLUSTERED ([ID] ASC)
);

Publication dans Azure

Pour plus d’informations sur le déploiement sur Azure, consultez Tutoriel : Créer une application ASP.NET Core dans Azure avec SQL Database.

Nous vous remercions d’avoir effectué cette introduction aux pages Razor. Pour compléter ce tutoriel, vous pouvez consulter Bien démarrer avec les Pages Razor et EF Core.

Modèles d’application web fiables

Consultez Le modèle d’application web fiable for.NETvidéos YouTube et l’article pour obtenir des conseils sur la création d’une application ASP.NET Core moderne, fiable, performante, testable, économique et évolutive, que ce soit à partir de zéro ou en refactorisant une application existante.

Ressources supplémentaires

Étapes suivantes