Pages Razor obtenues par génération de modèles automatique dans ASP.NET CoreScaffolded Razor Pages in ASP.NET Core

De Rick AndersonBy Rick Anderson

Ce didacticiel décrit les pages Razor créées par génération de modèles automatique au cours du didacticiel précédent.This tutorial examines the Razor Pages created by scaffolding in the previous tutorial.

Pages Create, Delete, Details et EditThe Create, Delete, Details, and Edit pages

Examinez le modèle de page Pages/Movies/Index.cshtml.cs :Examine the Pages/Movies/Index.cshtml.cs Page Model:

// Unused usings removed.
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using RazorPagesMovie.Models;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace RazorPagesMovie.Pages.Movies
{
    public class IndexModel : PageModel
    {
        private readonly RazorPagesMovie.Data.RazorPagesMovieContext _context;

        public IndexModel(RazorPagesMovie.Data.RazorPagesMovieContext context)
        {
            _context = context;
        }

        public IList<Movie> Movie { get;set; }

        public async Task OnGetAsync()
        {
            Movie = await _context.Movie.ToListAsync();
        }
    }
}

Les pages Razor sont dérivées de PageModel.Razor Pages are derived from PageModel. Par convention, la classe dérivée de PageModel s’appelle <PageName>Model.By convention, the PageModel-derived class is called <PageName>Model. Le constructeur utilise l’injection de dépendances pour ajouter RazorPagesMovieContext à la page.The constructor uses dependency injection to add the RazorPagesMovieContext to the page. Toutes les pages obtenues par génération de modèles automatique suivent ce modèle.All the scaffolded pages follow this pattern. Consultez Code asynchrone pour plus d’informations sur la programmation asynchrone avec Entity Framework.See Asynchronous code for more information on asynchronous programming with Entity Framework.

Quand une requête est effectuée pour la page, la méthode OnGetAsync retourne une liste de films à la page Razor.When a request is made for the page, the OnGetAsync method returns a list of movies to the Razor Page. OnGetAsync ou OnGet est appelé pour initialiser l’état de la page.OnGetAsync or OnGet is called to initialize the state of the page. Dans ce cas, OnGetAsync obtient une liste de films et les affiche.In this case, OnGetAsync gets a list of movies and displays them.

Lorsque OnGet retourne void ou OnGetAsync retourneTask, aucune instruction return n’est utilisée.When OnGet returns void or OnGetAsync returnsTask, no return statement is used. Lorsque le type de retour est IActionResult ou Task<IActionResult>, une instruction de retour doit être spécifiée.When the return type is IActionResult or Task<IActionResult>, a return statement must be provided. Par exemple, la méthode pages/movies/Create. cshtml. cs OnPostAsync :For example, the Pages/Movies/Create.cshtml.cs OnPostAsync method:

    public async Task<IActionResult> OnPostAsync()
    {
        if (!ModelState.IsValid)
        {
            return Page();
        }

        _context.Movie.Add(Movie);
        await _context.SaveChangesAsync();

        return RedirectToPage("./Index");
    }
}

Examinez la page Razor Pages/Movies/Index.cshtml :Examine the Pages/Movies/Index.cshtml Razor Page:

@page
@model RazorPagesMovie.Pages.Movies.IndexModel

@{
    ViewData["Title"] = "Index";
}

<h1>Index</h1>

<p>
    <a asp-page="Create">Create New</a>
</p>
<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].Title)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].ReleaseDate)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].Genre)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].Price)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
@foreach (var item in Model.Movie) {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.Title)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.ReleaseDate)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Genre)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Price)
            </td>
            <td>
                <a asp-page="./Edit" asp-route-id="@item.ID">Edit</a> |
                <a asp-page="./Details" asp-route-id="@item.ID">Details</a> |
                <a asp-page="./Delete" asp-route-id="@item.ID">Delete</a>
            </td>
        </tr>
}
    </tbody>
</table>

Razor peut passer du HTML au C# ou à des balises spécifiques à Razor.Razor can transition from HTML into C# or into Razor-specific markup. Quand un symbole @ est suivi d’un mot clé réservé Razor, il est converti en balise spécifique à Razor. Sinon, il est converti en C#.When an @ symbol is followed by a Razor reserved keyword, it transitions into Razor-specific markup, otherwise it transitions into C#.

Directive @pageThe @page directive

La directive Razor @page fait du fichier une action MVC, ce qui signifie qu’il peut gérer les demandes.The @page Razor directive makes the file an MVC action, which means that it can handle requests. @page doit être la première directive Razor sur une page.@page must be the first Razor directive on a page. @page est un exemple de conversion en balise spécifique à Razor.@page is an example of transitioning into Razor-specific markup. Pour plus d’informations, consultez Syntaxe Razor.See Razor syntax for more information.

Examinez l’expression lambda utilisée dans le Helper HTML suivant :Examine the lambda expression used in the following HTML Helper:

@Html.DisplayNameFor(model => model.Movie[0].Title)

Le HTML Helper DisplayNameFor inspecte la propriété Title référencée dans l’expression lambda pour déterminer le nom d’affichage.The DisplayNameFor HTML Helper inspects the Title property referenced in the lambda expression to determine the display name. L’expression lambda est inspectée plutôt qu’évaluée.The lambda expression is inspected rather than evaluated. Cela signifie qu’il n’y a aucune violation d’accès lorsque model, model.Movieou model.Movie[0] est null ou vide.That means there is no access violation when model, model.Movie, or model.Movie[0] is null or empty. Quand l’expression lambda est évaluée (par exemple avec @Html.DisplayFor(modelItem => item.Title)), les valeurs de propriété du modèle sont évaluées.When the lambda expression is evaluated (for example, with @Html.DisplayFor(modelItem => item.Title)), the model's property values are evaluated.

Directive @modelThe @model directive

@page
@model RazorPagesMovie.Pages.Movies.IndexModel

La directive @model spécifie le type du modèle passé à la page Razor.The @model directive specifies the type of the model passed to the Razor Page. Dans l’exemple précédent, la ligne @model rend la classe dérivée PageModel accessible à la page Razor.In the preceding example, the @model line makes the PageModel-derived class available to the Razor Page. Le modèle est utilisé dans le @Html.DisplayNameFor et @Html.DisplayFor des applications auxiliaires html sur la page.The model is used in the @Html.DisplayNameFor and @Html.DisplayFor HTML Helpers on the page.

La page de dispositionThe layout page

Sélectionnez les liens du menu (RazorPagesMovie, Accueil et Confidentialité).Select the menu links (RazorPagesMovie, Home, and Privacy). Chaque page affiche la même disposition de menu.Each page shows the same menu layout. La disposition du menu est implémentée dans le fichier Pages/Shared/_Layout.cshtml.The menu layout is implemented in the Pages/Shared/_Layout.cshtml file. Ouvrez le fichier Pages/Shared/_Layout.cshtml.Open the Pages/Shared/_Layout.cshtml file.

Les modèles de Disposition permettent que la disposition du conteneur HTML soit :Layout templates allow the HTML container layout to be:

  • spécifiée à un seul endroit ;Specified in one place.
  • appliquée à plusieurs pages du site.Applied in multiple pages in the site.

Recherchez la ligne @RenderBody().Find the @RenderBody() line. RenderBody est un espace réservé dans lequel toutes les vues propres à la page s’affichent, encapsulées dans la page de disposition.RenderBody is a placeholder where all the page-specific views show up, wrapped in the layout page. Par exemple, sélectionnez le lien Confidentialité et la vue Pages/Privacy.cshtml est restituée dans la méthode RenderBody.For example, select the Privacy link and the Pages/Privacy.cshtml view is rendered inside the RenderBody method.

ViewData et dispositionViewData and layout

Considérez la balise suivante du fichier Pages/Movies/Index.cshtml :Consider the following markup from the Pages/Movies/Index.cshtml file:

@page
@model RazorPagesMovie.Pages.Movies.IndexModel

@{
    ViewData["Title"] = "Index";
}

La balise précédente en surbrillance est un exemple de passage de Razor au C#.The preceding highlighted markup is an example of Razor transitioning into C#. Les caractères { et } délimitent un bloc de code C#.The { and } characters enclose a block of C# code.

La classe de base PageModel contient une propriété de dictionnaire ViewData qui peut être utilisée pour passer des données à une vue.The PageModel base class contains a ViewData dictionary property that can be used to pass data to a View. Des objets sont ajoutés au dictionnaire ViewData à l’aide d’un modèle clé/valeur.Objects are added to the ViewData dictionary using a key/value pattern. Dans l’exemple précédent, la propriété "Title" est ajoutée au dictionnaire ViewData.In the preceding sample, the "Title" property is added to the ViewData dictionary.

La propriété "Title" est utilisée dans le fichier Pages/Shared/_Layout.cshtml.The "Title" property is used in the Pages/Shared/_Layout.cshtml file. La balise suivante montre les premières lignes du fichier _Layout.cshtml.The following markup shows the first few lines of the _Layout.cshtml file.

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - RazorPagesMovie</title>

    @*Markup removed for brevity.*@

La ligne @*Markup removed for brevity.*@ est un commentaire Razor.The line @*Markup removed for brevity.*@ is a Razor comment. Contrairement aux commentaires HTML (<!-- -->), les commentaires Razor ne sont pas envoyés au client.Unlike HTML comments (<!-- -->), Razor comments are not sent to the client.

Mettre à jour la dispositionUpdate the layout

Changez l’élément <title> dans le fichier Pages/Shared/_Layout.cshtml pour afficher Movie au lieu de RazorPagesMovie.Change the <title> element in the Pages/Shared/_Layout.cshtml file to display Movie rather than RazorPagesMovie.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - Movie</title>

Recherchez l’élément anchor suivant dans le fichier Pages/Shared/_Layout.cshtml.Find the following anchor element in the Pages/Shared/_Layout.cshtml file.

<a class="navbar-brand" asp-area="" asp-page="/Index">RazorPagesMovie</a>

Remplacez l’élément précédent par la balise suivante :Replace the preceding element with the following markup:

<a class="navbar-brand" asp-page="/Movies/Index">RpMovie</a>

L’élément anchor précédent est un Tag Helper.The preceding anchor element is a Tag Helper. Dans le cas présent, il s’agit du Tag Helper d’ancre.In this case, it's the Anchor Tag Helper. L’attribut et la valeur du Tag Helper asp-page="/Movies/Index" créent un lien vers la page Razor /Movies/Index.The asp-page="/Movies/Index" Tag Helper attribute and value creates a link to the /Movies/Index Razor Page. La valeur de l’attribut asp-area est vide : la zone n’est donc pas utilisée dans le lien.The asp-area attribute value is empty, so the area isn't used in the link. Pour plus d’informations, consultez Zones.See Areas for more information.

Enregistrez vos changements, puis testez l’application en cliquant sur le lien RpMovie.Save your changes, and test the app by clicking on the RpMovie link. Consultez le fichier _Layout.cshtml dans GitHub si vous rencontrez des problèmes.See the _Layout.cshtml file in GitHub if you have any problems.

Testez les autres liens (Home, RpMovie, Create, Edit et Delete).Test the other links (Home, RpMovie, Create, Edit, and Delete). Chaque page définit le titre, que vous pouvez voir dans l’onglet navigateur. Lorsque vous ajoutez une page à un signet, le titre est utilisé pour le signet.Each page sets the title, which you can see in the browser tab. When you bookmark a page, the title is used for the bookmark.

Notes

Vous ne pourrez peut-être pas entrer de virgules décimales dans le champ Price.You may not be able to enter decimal commas in the Price field. 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.To support jQuery validation for non-English locales that use a comma (",") for a decimal point, and non US-English date formats, you must take steps to globalize your app. Consultez cette page GitHub problème 4076 pour savoir comment ajouter une virgule décimale.See this GitHub issue 4076 for instructions on adding decimal comma.

La propriété Layout est définie dans le fichier Pages/_ViewStart.cshtml :The Layout property is set in the Pages/_ViewStart.cshtml file:

@{
    Layout = "_Layout";
}

Le code précédent définit le fichier de disposition Pages/Shared/_Layout.cshtml pour tous les fichiers Razor du dossier Pages.The preceding markup sets the layout file to Pages/Shared/_Layout.cshtml for all Razor files under the Pages folder. Pour plus d’informations, consultez Disposition.See Layout for more information.

Le modèle de page CreateThe Create page model

Examinez le modèle de page Pages/Movies/Create.cshtml.cs :Examine the Pages/Movies/Create.cshtml.cs page model:

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using RazorPagesMovie.Models;
using System;
using System.Threading.Tasks;

namespace RazorPagesMovie.Pages.Movies
{
    public class CreateModel : PageModel
    {
        private readonly RazorPagesMovie.Data.RazorPagesMovieContext _context;

        public CreateModel(RazorPagesMovie.Data.RazorPagesMovieContext context)
        {
            _context = context;
        }

        public IActionResult OnGet()
        {
            return Page();
        }

        [BindProperty]
        public Movie Movie { get; set; }

        public async Task<IActionResult> OnPostAsync()
        {
            if (!ModelState.IsValid)
            {
                return Page();
            }

            _context.Movie.Add(Movie);
            await _context.SaveChangesAsync();

            return RedirectToPage("./Index");
        }
    }
}

La méthode OnGet initialise l’état nécessaire pour la page.The OnGet method initializes any state needed for the page. La page Create n’ayant aucun état à initialiser, Page est retourné.The Create page doesn't have any state to initialize, so Page is returned. Plus loin dans le tutoriel, un exemple d’état d’initialisation OnGet est affiché.Later in the tutorial, an example of OnGet initializing state is shown. La méthode Page crée un objet PageResult qui affiche la page Create.cshtml.The Page method creates a PageResult object that renders the Create.cshtml page.

La propriété Movie utilise l’attribut [BindProperty] pour adhérer à la liaison de données.The Movie property uses the [BindProperty] attribute to opt-in to model binding. Quand le formulaire Create publie les valeurs de formulaire, le runtime ASP.NET Core lie les valeurs publiées au modèle Movie.When the Create form posts the form values, the ASP.NET Core runtime binds the posted values to the Movie model.

La méthode OnPostAsync est exécutée quand la page publie les données de formulaire :The OnPostAsync method is run when the page posts form data:

public async Task<IActionResult> OnPostAsync()
{
    if (!ModelState.IsValid)
    {
        return Page();
    }

    _context.Movie.Add(Movie);
    await _context.SaveChangesAsync();

    return RedirectToPage("./Index");
}

S’il existe des erreurs liées au modèle, le formulaire est réaffiché, ainsi que toutes les données de formulaire publiées.If there are any model errors, the form is redisplayed, along with any form data posted. La plupart des erreurs de modèle peuvent être interceptées côté client avant la publication du formulaire.Most model errors can be caught on the client-side before the form is posted. Voici un exemple d’erreur de modèle : la publication pour le champ de date d’une valeur qui ne peut pas être convertie en date.An example of a model error is posting a value for the date field that cannot be converted to a date. La validation côté client et la validation du modèle sont présentées plus loin dans le tutoriel.Client-side validation and model validation are discussed later in the tutorial.

S’il n’existe pas d’erreurs de modèle, les données sont enregistrées et le navigateur est redirigé vers la page Index.If there are no model errors, the data is saved, and the browser is redirected to the Index page.

Page Razor CreateThe Create Razor Page

Examinez le fichier de la page Razor Pages/Movies/Create.cshtml :Examine the Pages/Movies/Create.cshtml Razor Page file:

@page
@model RazorPagesMovie.Pages.Movies.CreateModel

@{
    ViewData["Title"] = "Create";
}

<h1>Create</h1>

<h4>Movie</h4>
<hr />
<div class="row">
    <div class="col-md-4">
        <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>
            <div class="form-group">
                <label asp-for="Movie.ReleaseDate" class="control-label"></label>
                <input asp-for="Movie.ReleaseDate" class="form-control" />
                <span asp-validation-for="Movie.ReleaseDate" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Movie.Genre" class="control-label"></label>
                <input asp-for="Movie.Genre" class="form-control" />
                <span asp-validation-for="Movie.Genre" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Movie.Price" class="control-label"></label>
                <input asp-for="Movie.Price" class="form-control" />
                <span asp-validation-for="Movie.Price" class="text-danger"></span>
            </div>
            <div class="form-group">
                <input type="submit" value="Create" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>

<div>
    <a asp-page="Index">Back to List</a>
</div>

@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}

Visual Studio affiche la balise suivante dans une police différenciée en gras utilisée pour les Tag Helpers :Visual Studio displays the following tags in a distinctive bold font used for Tag Helpers:

  • <form method="post">
  • <div asp-validation-summary="ModelOnly" class="text-danger"></div>
  • <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>

Vue VS17 de la page Create.cshtml

L’élément <form method="post"> est un Tag Helper de formulaire.The <form method="post"> element is a Form Tag Helper. Le Tag Helper de formulaire inclut automatiquement un jeton de protection contre les falsifications.The Form Tag Helper automatically includes an antiforgery token.

Le moteur de génération de modèles automatique crée le code Razor pour chaque champ du modèle (sauf l’ID) de la manière suivante :The scaffolding engine creates Razor markup for each field in the model (except the ID) similar to the following:

<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>

Les Tag Helpers de validation (<div asp-validation-summary et <span asp-validation-for) affichent des erreurs de validation.The Validation Tag Helpers (<div asp-validation-summary and <span asp-validation-for) display validation errors. La validation est traitée de manière plus détaillée plus loin dans cette série.Validation is covered in more detail later in this series.

Le Tag Helper d’étiquette (<label asp-for="Movie.Title" class="control-label"></label>) génère la légende de l’étiquette et l’attribut for pour la propriété Title.The Label Tag Helper (<label asp-for="Movie.Title" class="control-label"></label>) generates the label caption and for attribute for the Title property.

Le Tag Helper d’entrée (<input asp-for="Movie.Title" class="form-control">) utilise les attributs DataAnnotations et produit les attributs HTML nécessaires à la validation jQuery côté client.The Input Tag Helper (<input asp-for="Movie.Title" class="form-control">) uses the DataAnnotations attributes and produces HTML attributes needed for jQuery Validation on the client-side.

Pour plus d’informations sur les Tag Helpers, comme <form method="post">, consultez Tag Helpers dans ASP.NET Core.For more information on Tag Helpers such as <form method="post">, see Tag Helpers in ASP.NET Core.

Ressources supplémentairesAdditional resources

De Rick AndersonBy Rick Anderson

Ce didacticiel décrit les pages Razor créées par génération de modèles automatique au cours du didacticiel précédent.This tutorial examines the Razor Pages created by scaffolding in the previous tutorial.

Affichez ou téléchargez l’exemple.View or download sample.

Pages Create, Delete, Details et EditThe Create, Delete, Details, and Edit pages

Examinez le modèle de page Pages/Movies/Index.cshtml.cs :Examine the Pages/Movies/Index.cshtml.cs Page Model:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using RazorPagesMovie.Models;

namespace RazorPagesMovie.Pages.Movies
{
    public class IndexModel : PageModel
    {
        private readonly RazorPagesMovie.Models.RazorPagesMovieContext _context;

        public IndexModel(RazorPagesMovie.Models.RazorPagesMovieContext context)
        {
            _context = context;
        }

        public IList<Movie> Movie { get;set; }

        public async Task OnGetAsync()
        {
            Movie = await _context.Movie.ToListAsync();
        }
    }
}

Les pages Razor sont dérivées de PageModel.Razor Pages are derived from PageModel. Par convention, la classe dérivée de PageModel s’appelle <PageName>Model.By convention, the PageModel-derived class is called <PageName>Model. Le constructeur utilise l’injection de dépendances pour ajouter RazorPagesMovieContext à la page.The constructor uses dependency injection to add the RazorPagesMovieContext to the page. Toutes les pages obtenues par génération de modèles automatique suivent ce modèle.All the scaffolded pages follow this pattern. Consultez Code asynchrone pour plus d’informations sur la programmation asynchrone avec Entity Framework.See Asynchronous code for more information on asynchronous programming with Entity Framework.

Quand une requête est effectuée pour la page, la méthode OnGetAsync retourne une liste de films à la page Razor.When a request is made for the page, the OnGetAsync method returns a list of movies to the Razor Page. OnGetAsync ou OnGet est appelé sur une page Razor pour initialiser l’état de la page.OnGetAsync or OnGet is called on a Razor Page to initialize the state for the page. Dans ce cas, OnGetAsync obtient une liste de films et les affiche.In this case, OnGetAsync gets a list of movies and displays them.

Si OnGet retourne void ou que OnGetAsync retourne Task, aucune méthode de retour n’est utilisée.When OnGet returns void or OnGetAsync returnsTask, no return method is used. Lorsque le type de retour est IActionResult ou Task<IActionResult>, une instruction de retour doit être spécifiée.When the return type is IActionResult or Task<IActionResult>, a return statement must be provided. Par exemple, la méthode pages/movies/Create. cshtml. cs OnPostAsync :For example, the Pages/Movies/Create.cshtml.cs OnPostAsync method:

public async Task<IActionResult> OnPostAsync()
{
    if (!ModelState.IsValid)
    {
        return Page();
    }

    _context.Movie.Add(Movie);
    await _context.SaveChangesAsync();

    return RedirectToPage("./Index");
}

Examinez la page Razor Pages/Movies/Index.cshtml :Examine the Pages/Movies/Index.cshtml Razor Page:

@page
@model RazorPagesMovie.Pages.Movies.IndexModel

@{
    ViewData["Title"] = "Index";
}

<h1>Index</h1>

<p>
    <a asp-page="Create">Create New</a>
</p>
<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].Title)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].ReleaseDate)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].Genre)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].Price)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
@foreach (var item in Model.Movie) {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.Title)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.ReleaseDate)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Genre)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Price)
            </td>
            <td>
                <a asp-page="./Edit" asp-route-id="@item.ID">Edit</a> |
                <a asp-page="./Details" asp-route-id="@item.ID">Details</a> |
                <a asp-page="./Delete" asp-route-id="@item.ID">Delete</a>
            </td>
        </tr>
}
    </tbody>
</table>

Razor peut passer du HTML au C# ou à des balises spécifiques à Razor.Razor can transition from HTML into C# or into Razor-specific markup. Quand un symbole @ est suivi d’un mot clé réservé Razor, il est converti en balise spécifique à Razor. Sinon, il est converti en C#.When an @ symbol is followed by a Razor reserved keyword, it transitions into Razor-specific markup, otherwise it transitions into C#.

La directive Razor @page transforme le fichier en une action MVC, ce qui lui permet de prendre en charge des requêtes.The @page Razor directive makes the file into an MVC action, which means that it can handle requests. @page doit être la première directive Razor sur une page.@page must be the first Razor directive on a page. @page est un exemple de conversion en balise spécifique à Razor.@page is an example of transitioning into Razor-specific markup. Pour plus d’informations, consultez Syntaxe Razor.See Razor syntax for more information.

Examinez l’expression lambda utilisée dans le Helper HTML suivant :Examine the lambda expression used in the following HTML Helper:

@Html.DisplayNameFor(model => model.Movie[0].Title)

Le HTML Helper DisplayNameFor inspecte la propriété Title référencée dans l’expression lambda pour déterminer le nom d’affichage.The DisplayNameFor HTML Helper inspects the Title property referenced in the lambda expression to determine the display name. L’expression lambda est inspectée plutôt qu’évaluée.The lambda expression is inspected rather than evaluated. Cela signifie qu’il n’existe pas de violation d’accès quand model, model.Movie ou model.Movie[0] ont une valeur null ou vide.That means there is no access violation when model, model.Movie, or model.Movie[0] are null or empty. Quand l’expression lambda est évaluée (par exemple avec @Html.DisplayFor(modelItem => item.Title)), les valeurs de propriété du modèle sont évaluées.When the lambda expression is evaluated (for example, with @Html.DisplayFor(modelItem => item.Title)), the model's property values are evaluated.

Directive @modelThe @model directive

@page
@model RazorPagesMovie.Pages.Movies.IndexModel

La directive @model spécifie le type du modèle passé à la page Razor.The @model directive specifies the type of the model passed to the Razor Page. Dans l’exemple précédent, la ligne @model rend la classe dérivée PageModel accessible à la page Razor.In the preceding example, the @model line makes the PageModel-derived class available to the Razor Page. Le modèle est utilisé dans le @Html.DisplayNameFor et @Html.DisplayFor des applications auxiliaires html sur la page.The model is used in the @Html.DisplayNameFor and @Html.DisplayFor HTML Helpers on the page.

La page de dispositionThe layout page

Sélectionnez les liens du menu (RazorPagesMovie, Accueil et Confidentialité).Select the menu links (RazorPagesMovie, Home, and Privacy). Chaque page affiche la même disposition de menu.Each page shows the same menu layout. La disposition du menu est implémentée dans le fichier Pages/Shared/_Layout.cshtml.The menu layout is implemented in the Pages/Shared/_Layout.cshtml file. Ouvrez le fichier Pages/Shared/_Layout.cshtml.Open the Pages/Shared/_Layout.cshtml file.

Les modèles de disposition vous permettent de spécifier la disposition du conteneur HTML de votre site dans un emplacement unique, puis de l’appliquer sur plusieurs pages de votre site.Layout templates allow you to specify the HTML container layout of your site in one place and then apply it across multiple pages in your site. Recherchez la ligne @RenderBody().Find the @RenderBody() line. RenderBody est un espace réservé dans lequel toutes les vues spécifiques à une page que vous créez s’affichent, encapsulées dans la page de disposition.RenderBody is a placeholder where all the page-specific views you create show up, wrapped in the layout page. Par exemple, si vous sélectionnez le lien Confidentialité, la vue Pages/Privacy.cshtml est restituée dans la méthode RenderBody.For example, if you select the Privacy link, the Pages/Privacy.cshtml view is rendered inside the RenderBody method.

ViewData et dispositionViewData and layout

Considérez le code suivant du fichier Pages/Movies/Index.cshtml:Consider the following code from the Pages/Movies/Index.cshtml file:

@page
@model RazorPagesMovie.Pages.Movies.IndexModel

@{
    ViewData["Title"] = "Index";
}

Le code précédent en surbrillance est un exemple de passage de Razor au C#.The preceding highlighted code is an example of Razor transitioning into C#. Les caractères { et } délimitent un bloc de code C#.The { and } characters enclose a block of C# code.

La classe de base PageModel a une propriété de dictionnaire ViewData qui permet d’ajouter des données à passer à une vue.The PageModel base class has a ViewData dictionary property that can be used to add data that you want to pass to a View. Vous pouvez ajouter des objets au dictionnaire ViewData à l’aide d’un modèle clé/valeur.You add objects into the ViewData dictionary using a key/value pattern. Dans l’exemple précédent, la propriété « Title » est ajoutée au dictionnaire ViewData.In the preceding sample, the "Title" property is added to the ViewData dictionary.

La propriété « Title » est utilisée dans le fichier Pages/Shared/_Layout.cshtml.The "Title" property is used in the Pages/Shared/_Layout.cshtml file. La balise suivante montre les premières lignes du fichier _Layout.cshtml.The following markup shows the first few lines of the _Layout.cshtml file.

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - RazorPagesMovie</title>

    @*Markup removed for brevity.*@

La ligne @*Markup removed for brevity.*@ est un commentaire Razor qui n’apparaît pas dans votre fichier de disposition.The line @*Markup removed for brevity.*@ is a Razor comment which doesn't appear in your layout file. Contrairement aux commentaires HTML (<!-- -->), les commentaires Razor ne sont pas envoyés au client.Unlike HTML comments (<!-- -->), Razor comments are not sent to the client.

Mettre à jour la dispositionUpdate the layout

Changez l’élément <title> dans le fichier Pages/Shared/_Layout.cshtml pour afficher Movie au lieu de RazorPagesMovie.Change the <title> element in the Pages/Shared/_Layout.cshtml file to display Movie rather than RazorPagesMovie.

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - Movie</title>

Recherchez l’élément anchor suivant dans le fichier Pages/Shared/_Layout.cshtml.Find the following anchor element in the Pages/Shared/_Layout.cshtml file.

<a class="navbar-brand" asp-area="" asp-page="/Index">RazorPagesMovie</a>

Remplacez l’élément précédent par le code suivant.Replace the preceding element with the following markup.

<a class="navbar-brand" asp-page="/Movies/Index">RpMovie</a>

L’élément anchor précédent est un Tag Helper.The preceding anchor element is a Tag Helper. Dans le cas présent, il s’agit du Tag Helper d’ancre.In this case, it's the Anchor Tag Helper. L’attribut et la valeur du Tag Helper asp-page="/Movies/Index" créent un lien vers la page Razor /Movies/Index.The asp-page="/Movies/Index" Tag Helper attribute and value creates a link to the /Movies/Index Razor Page. La valeur de l’attribut asp-area est vide : la zone n’est donc pas utilisée dans le lien.The asp-area attribute value is empty, so the area isn't used in the link. Pour plus d’informations, consultez Zones.See Areas for more information.

Enregistrez vos changements, puis testez l’application en cliquant sur le lien RpMovie.Save your changes, and test the app by clicking on the RpMovie link. Consultez le fichier _Layout.cshtml dans GitHub si vous rencontrez des problèmes.See the _Layout.cshtml file in GitHub if you have any problems.

Testez les autres liens (Home, RpMovie, Create, Edit et Delete).Test the other links (Home, RpMovie, Create, Edit, and Delete). Chaque page définit le titre, que vous pouvez voir dans l’onglet navigateur. Lorsque vous ajoutez une page à un signet, le titre est utilisé pour le signet.Each page sets the title, which you can see in the browser tab. When you bookmark a page, the title is used for the bookmark.

Notes

Vous ne pourrez peut-être pas entrer de virgules décimales dans le champ Price.You may not be able to enter decimal commas in the Price field. 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.To support jQuery validation for non-English locales that use a comma (",") for a decimal point, and non US-English date formats, you must take steps to globalize your app. Consultez la page GitHub problème 4076 pour savoir comment ajouter une virgule décimale.This GitHub issue 4076 for instructions on adding decimal comma.

La propriété Layout est définie dans le fichier Pages/_ViewStart.cshtml :The Layout property is set in the Pages/_ViewStart.cshtml file:

@{
    Layout = "_Layout";
}

Le code précédent définit le fichier de disposition Pages/Shared/_Layout.cshtml pour tous les fichiers Razor du dossier Pages.The preceding markup sets the layout file to Pages/Shared/_Layout.cshtml for all Razor files under the Pages folder. Pour plus d’informations, consultez Disposition.See Layout for more information.

Le modèle de page CreateThe Create page model

Examinez le modèle de page Pages/Movies/Create.cshtml.cs :Examine the Pages/Movies/Create.cshtml.cs page model:

// Unused usings removed.
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using RazorPagesMovie.Models;
using System;
using System.Threading.Tasks;

namespace RazorPagesMovie.Pages.Movies
{
    public class CreateModel : PageModel
    {
        private readonly RazorPagesMovie.Models.RazorPagesMovieContext _context;

        public CreateModel(RazorPagesMovie.Models.RazorPagesMovieContext context)
        {
            _context = context;
        }

        public IActionResult OnGet()
        {
            return Page();
        }

        [BindProperty]
        public Movie Movie { get; set; }

        public async Task<IActionResult> OnPostAsync()
        {
            if (!ModelState.IsValid)
            {
                return Page();
            }

            _context.Movie.Add(Movie);
            await _context.SaveChangesAsync();

            return RedirectToPage("./Index");
        }
    }
}

La méthode OnGet initialise l’état nécessaire pour la page.The OnGet method initializes any state needed for the page. La page Create n’ayant aucun état à initialiser, Page est retourné.The Create page doesn't have any state to initialize, so Page is returned. Ce tutoriel illustre plus loin l’initialisation de l’état par la méthode OnGet.Later in the tutorial you see OnGet method initialize state. La méthode Page crée un objet PageResult qui affiche la page Create.cshtml.The Page method creates a PageResult object that renders the Create.cshtml page.

La propriété Movie utilise l’attribut [BindProperty] pour adhérer à la liaison de données.The Movie property uses the [BindProperty] attribute to opt-in to model binding. Quand le formulaire Create publie les valeurs de formulaire, le runtime ASP.NET Core lie les valeurs publiées au modèle Movie.When the Create form posts the form values, the ASP.NET Core runtime binds the posted values to the Movie model.

La méthode OnPostAsync est exécutée quand la page publie les données de formulaire :The OnPostAsync method is run when the page posts form data:

public async Task<IActionResult> OnPostAsync()
{
    if (!ModelState.IsValid)
    {
        return Page();
    }

    _context.Movie.Add(Movie);
    await _context.SaveChangesAsync();

    return RedirectToPage("./Index");
}

S’il existe des erreurs liées au modèle, le formulaire est réaffiché, ainsi que toutes les données de formulaire publiées.If there are any model errors, the form is redisplayed, along with any form data posted. La plupart des erreurs de modèle peuvent être interceptées côté client avant la publication du formulaire.Most model errors can be caught on the client-side before the form is posted. Voici un exemple d’erreur de modèle : la publication pour le champ de date d’une valeur qui ne peut pas être convertie en date.An example of a model error is posting a value for the date field that cannot be converted to a date. La validation côté client et la validation du modèle sont présentées plus loin dans le tutoriel.Client-side validation and model validation are discussed later in the tutorial.

S’il n’existe pas d’erreurs de modèle, les données sont enregistrées et le navigateur est redirigé vers la page Index.If there are no model errors, the data is saved, and the browser is redirected to the Index page.

Page Razor CreateThe Create Razor Page

Examinez le fichier de la page Razor Pages/Movies/Create.cshtml :Examine the Pages/Movies/Create.cshtml Razor Page file:

@page
@model RazorPagesMovie.Pages.Movies.CreateModel

@{
    ViewData["Title"] = "Create";
}

<h1>Create</h1>

<h4>Movie</h4>
<hr />
<div class="row">
    <div class="col-md-4">
        <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>
            <div class="form-group">
                <label asp-for="Movie.ReleaseDate" class="control-label"></label>
                <input asp-for="Movie.ReleaseDate" class="form-control" />
                <span asp-validation-for="Movie.ReleaseDate" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Movie.Genre" class="control-label"></label>
                <input asp-for="Movie.Genre" class="form-control" />
                <span asp-validation-for="Movie.Genre" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Movie.Price" class="control-label"></label>
                <input asp-for="Movie.Price" class="form-control" />
                <span asp-validation-for="Movie.Price" class="text-danger"></span>
            </div>
            <div class="form-group">
                <input type="submit" value="Create" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>

<div>
    <a asp-page="Index">Back to List</a>
</div>

@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}

Visual Studio affiche la balise <form method="post"> dans une police différenciée en gras utilisée pour les Tag Helpers :Visual Studio displays the <form method="post"> tag in a distinctive bold font used for Tag Helpers:

Vue VS17 de la page Create.cshtml

L’élément <form method="post"> est un Tag Helper de formulaire.The <form method="post"> element is a Form Tag Helper. Le Tag Helper de formulaire inclut automatiquement un jeton de protection contre les falsifications.The Form Tag Helper automatically includes an antiforgery token.

Le moteur de génération de modèles automatique crée le code Razor pour chaque champ du modèle (sauf l’ID) de la manière suivante :The scaffolding engine creates Razor markup for each field in the model (except the ID) similar to the following:

<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>

Les Tag Helpers de validation (<div asp-validation-summary et <span asp-validation-for) affichent des erreurs de validation.The Validation Tag Helpers (<div asp-validation-summary and <span asp-validation-for) display validation errors. La validation est traitée de manière plus détaillée plus loin dans cette série.Validation is covered in more detail later in this series.

Le Tag Helper d’étiquette (<label asp-for="Movie.Title" class="control-label"></label>) génère la légende de l’étiquette et l’attribut for pour la propriété Title.The Label Tag Helper (<label asp-for="Movie.Title" class="control-label"></label>) generates the label caption and for attribute for the Title property.

Le Tag Helper d’entrée (<input asp-for="Movie.Title" class="form-control">) utilise les attributs DataAnnotations et produit les attributs HTML nécessaires à la validation jQuery côté client.The Input Tag Helper (<input asp-for="Movie.Title" class="form-control">) uses the DataAnnotations attributes and produces HTML attributes needed for jQuery Validation on the client-side.

Ressources supplémentairesAdditional resources