Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Opmerking
Dit is niet de nieuwste versie van dit artikel. Zie de .NET 9-versie van dit artikel voor de huidige release.
Waarschuwing
Deze versie van ASP.NET Core wordt niet meer ondersteund. Zie het .NET- en .NET Core-ondersteuningsbeleid voor meer informatie. Zie de .NET 9-versie van dit artikel voor de huidige release.
Belangrijk
Deze informatie heeft betrekking op een pre-releaseproduct dat aanzienlijk kan worden gewijzigd voordat het commercieel wordt uitgebracht. Microsoft geeft geen garanties, uitdrukkelijk of impliciet, met betrekking tot de informatie die hier wordt verstrekt.
Zie de .NET 9-versie van dit artikel voor de huidige release.
Door Rick Anderson
In deze zelfstudie worden de pagina's die door scaffolding zijn gemaakt in de Razor onderzocht.
De pagina's Maken, Verwijderen, Details en Bewerken
Bekijk het Pages/Movies/Index.cshtml.cs
paginamodel:
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.Data;
using RazorPagesMovie.Models;
using Microsoft.AspNetCore.Mvc.Rendering;
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; } = default!;
public async Task OnGetAsync()
{
Movie = await _context.Movie.ToListAsync();
}
}
}
Razor Pagina's zijn afgeleid van PageModel. Volgens conventie heeft de afgeleide klasse de PageModel
naam PageNameModel
. De indexpagina heeft bijvoorbeeld de naam IndexModel
.
De constructor gebruikt afhankelijkheidsinjectie om RazorPagesMovieContext
aan de pagina toe te voegen.
public class IndexModel : PageModel
{
private readonly RazorPagesMovie.Data.RazorPagesMovieContext _context;
public IndexModel(RazorPagesMovie.Data.RazorPagesMovieContext context)
{
_context = context;
}
Zie Asynchrone code voor meer informatie over asynchrone programmering met Entity Framework.
Wanneer er een GET
aanvraag voor de pagina wordt ingediend, retourneert de OnGetAsync
methode een lijst met films naar de Razor pagina. Op een Razor pagina OnGetAsync
of OnGet
wordt aangeroepen om de status van de pagina te initialiseren. In dit geval haalt OnGetAsync
een lijst met films op en geeft deze weer.
Wanneer OnGet
void
teruggeeft of OnGetAsync
Task
teruggeeft, wordt er geen return-statement gebruikt. Bekijk bijvoorbeeld de Privacy pagina:
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace RazorPagesMovie.Pages
{
public class PrivacyModel : PageModel
{
private readonly ILogger<PrivacyModel> _logger;
public PrivacyModel(ILogger<PrivacyModel> logger)
{
_logger = logger;
}
public void OnGet()
{
}
}
}
Wanneer het retourtype IActionResult of Task<IActionResult>
is, moet er een returninstructie worden opgegeven. Bijvoorbeeld de Pages/Movies/Create.cshtml.cs OnPostAsync
methode:
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
_context.Movie.Add(Movie);
await _context.SaveChangesAsync();
return RedirectToPage("./Index");
}
Bekijk de Pages/Movies/Index.cshtml
Razor pagina:
@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 kan worden overgestapt van HTML naar C# of naar Razor-specifieke markeringen. Wanneer een @
symbool wordt gevolgd door een Razor gereserveerd trefwoord, wordt het overgegaan naar Razor-specifieke markeringen, anders wordt het overgegaan naar C#.
De richtlijn @page
De @page
Razor instructie maakt het bestand een MVC-actie, wat betekent dat het aanvragen kan verwerken.
@page
moet de eerste Razor instructie op een pagina zijn.
@page
en @model
zijn voorbeelden van overgang naar Razor-specifieke markeringen. Zie Razor de syntaxis voor meer informatie.
De richtlijn @model
@page
@model RazorPagesMovie.Pages.Movies.IndexModel
De @model
richtlijn geeft het type model aan dat aan de Razor pagina wordt doorgegeven. In het voorgaande voorbeeld maakt de @model
regel de PageModel
afgeleide klasse beschikbaar voor de Razor pagina. Het model wordt gebruikt in de @Html.DisplayNameFor
@Html.DisplayFor
HTML-Helpers op de pagina.
Bekijk de lambda-expressie die wordt gebruikt in de volgende HTML-helper:
@Html.DisplayNameFor(model => model.Movie[0].Title)
De DisplayNameFor HTML Helper inspecteert de Title
eigenschap waarnaar wordt verwezen in de lambda-expressie om de weergavenaam te bepalen. De lambda-expressie wordt geïnspecteerd in plaats van geëvalueerd. Dit betekent dat er geen toegangsschending is wanneer model
, model.Movie
, of model.Movie[0]
null
of leeg is. Wanneer de lambda-expressie wordt geëvalueerd, bijvoorbeeld met @Html.DisplayFor(modelItem => item.Title)
, worden de eigenschapswaarden van het model geëvalueerd.
De indelingspagina
Selecteer de menukoppelingen RazorPagesMovie, Home, en Privacy. Elke pagina bevat dezelfde menu-indeling. De menu-indeling wordt geïmplementeerd in het Pages/Shared/_Layout.cshtml
bestand.
Open het Pages/Shared/_Layout.cshtml
bestand en bekijk het.
Met indelingssjablonen kan de HTML-containerindeling het volgende zijn:
- Gespecificeerd op één plaats.
- Toegepast op meerdere pagina's op de site.
Zoek de @RenderBody()
lijn.
RenderBody
is een tijdelijke aanduiding waarin alle paginaspecifieke weergaven worden weergegeven, verpakt op de indelingspagina. Selecteer bijvoorbeeld de Privacy koppeling en de Pages/Privacy.cshtml
weergave wordt weergegeven in de RenderBody
methode.
Weergavegegevens en layout
Houd rekening met de volgende markeringen uit het Pages/Movies/Index.cshtml
bestand:
@page
@model RazorPagesMovie.Pages.Movies.IndexModel
@{
ViewData["Title"] = "Index";
}
De vooraf gemarkeerde markeringen zijn een voorbeeld van Razor dat overgaat naar C#. De {
tekens en }
bevatten een blok C#-code.
De PageModel
basisklasse bevat een ViewData
woordenlijsteigenschap die kan worden gebruikt om gegevens door te geven aan een weergave. Objecten worden aan de ViewData
woordenlijst toegevoegd met behulp van een sleutelwaardepatroon . In het voorgaande voorbeeld wordt de Title
eigenschap toegevoegd aan de ViewData
woordenlijst.
De Title
eigenschap wordt gebruikt in het Pages/Shared/_Layout.cshtml
bestand. In de volgende markeringen worden de eerste regels van het _Layout.cshtml
bestand weergegeven.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - RazorPagesMovie</title>
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
<link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
<link rel="stylesheet" href="~/RazorPagesMovie.styles.css" asp-append-version="true" />
De indeling bijwerken
Wijzig het
<title>
element in hetPages/Shared/_Layout.cshtml
bestand om Film weer te geven in plaats van 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>
Zoek het volgende ankerelement in het
Pages/Shared/_Layout.cshtml
bestand.<a class="navbar-brand" asp-area="" asp-page="/Index">RazorPagesMovie</a>
Vervang het voorgaande element door de volgende markeringen:
<a class="navbar-brand" asp-page="/Movies/Index">RpMovie</a>
Het voorgaande ankerelement is een Tag Helper. In dit geval is het de Anchor Tag Helper. Het
asp-page="/Movies/Index"
Tag Helper-kenmerk en -waarde maken een koppeling naar de/Movies/Index
Razor pagina. Deasp-area
kenmerkwaarde is leeg, dus het gebied wordt niet gebruikt in de koppeling. Zie Gebieden voor meer informatie.Sla de wijzigingen op en test de app door de RpMovie-koppeling te selecteren. Zie het bestand _Layout.cshtml in GitHub als u problemen ondervindt.
Test de koppelingen Home, RpMovie, Maken, Bewerken en Verwijderen. Op elke pagina wordt de titel ingesteld die je in het tabblad van de browser kunt zien. Wanneer je een pagina als bladwijzer opslaat, wordt de titel gebruikt voor de bladwijzer.
Opmerking
Mogelijk kunt u geen decimale komma's invoeren in het veld Price
. Als u jQuery-validatie wilt ondersteunen voor niet-Engelse landinstellingen die een komma (",") gebruiken voor een decimaalteken en niet-US-English datumnotaties, moet u stappen ondernemen om de app te globaliseren. Zie dit GitHub-probleem 4076 voor instructies over het toevoegen van decimale komma's.
De Layout
eigenschap is ingesteld in het Pages/_ViewStart.cshtml
bestand:
@{
Layout = "_Layout";
}
Met de voorgaande opmaak wordt het indelingsbestand ingesteld Pages/Shared/_Layout.cshtml
op alle Razor bestanden onder de map Pagina's . Zie Indeling voor meer informatie.
Het paginamodel maken
Bekijk het Pages/Movies/Create.cshtml.cs
paginamodel:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.Mvc.Rendering;
using RazorPagesMovie.Data;
using RazorPagesMovie.Models;
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; } = default!;
// To protect from overposting attacks, see https://aka.ms/RazorPagesCRUD
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
_context.Movie.Add(Movie);
await _context.SaveChangesAsync();
return RedirectToPage("./Index");
}
}
}
De OnGet
methode initialiseert alle statussen die nodig zijn voor de pagina. De Maakpagina heeft geen status die hoeft te worden geïnitialiseerd, dus Page
wordt geretourneerd. Verderop in de zelfstudie wordt een voorbeeld van OnGet
de initialisatiestatus weergegeven. Met de Page
methode wordt een PageResult
object gemaakt waarmee de Create.cshtml
pagina wordt weergegeven.
De Movie
eigenschap maakt gebruik van het kenmerk [BindProperty] om deel te nemen aan modelbinding. Wanneer het formulier maken de formulierwaarden plaatst, verbindt de ASP.NET Core-runtime de geplaatste waarden aan het Movie
model.
De OnPostAsync
methode wordt uitgevoerd wanneer de formuliergegevens van de pagina worden geplaatst:
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
_context.Movie.Add(Movie);
await _context.SaveChangesAsync();
return RedirectToPage("./Index");
}
Als er modelfouten zijn, wordt het formulier opnieuw weergegeven, samen met eventuele formuliergegevens die zijn gepost. De meeste modelfouten kunnen aan de clientzijde worden opgevangen voordat het formulier wordt geplaatst. Een voorbeeld van een modelfout is het posten van een waarde voor het datumveld dat niet kan worden geconverteerd naar een datum. Validatie aan de clientzijde en modelvalidatie worden verderop in de zelfstudie besproken.
Als er geen modelfouten zijn:
- De gegevens worden opgeslagen.
- De browser wordt omgeleid naar de pagina Index.
De pagina Maken Razor
Bekijk het Pages/Movies/Create.cshtml
Razor paginabestand:
@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 geeft de volgende tags weer in een opvallend vet lettertype dat wordt gebruikt voor 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>
Het <form method="post">
element is een Helper voor formuliertags. De Helper voor formuliertags bevat automatisch een antiforgery-token.
De scaffolding-engine creëert Razor markup voor elk veld in het model, behalve de ID, zoals de volgende:
<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>
In de Helpers voor validatietags (<div asp-validation-summary
en <span asp-validation-for
) worden validatiefouten weergegeven. De validatie wordt verderop in deze reeks uitgebreider besproken.
De Label Tag Helper (<label asp-for="Movie.Title" class="control-label"></label>
) genereert het labelbijschrift en [for]
kenmerk voor de Title
eigenschap.
De Helper voor invoertags (<input asp-for="Movie.Title" class="form-control">
) maakt gebruik van de kenmerken DataAnnotations en produceert HTML-kenmerken die nodig zijn voor jQuery-validatie aan de clientzijde.
Zie <form method="post">
voor meer informatie over Tag Helpers zoals.
Volgende stappen
De pagina's Maken, Verwijderen, Details en Bewerken
Bekijk het Pages/Movies/Index.cshtml.cs
paginamodel:
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using RazorPagesMovie.Models;
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; } = default!;
public async Task OnGetAsync()
{
if (_context.Movie != null)
{
Movie = await _context.Movie.ToListAsync();
}
}
}
Razor Pagina's zijn afgeleid van PageModel. Volgens conventie heeft de afgeleide klasse de PageModel
naam PageNameModel
. De indexpagina heeft bijvoorbeeld de naam IndexModel
.
De constructor gebruikt afhankelijkheidsinjectie om RazorPagesMovieContext
aan de pagina toe te voegen.
public class IndexModel : PageModel
{
private readonly RazorPagesMovie.Data.RazorPagesMovieContext _context;
public IndexModel(RazorPagesMovie.Data.RazorPagesMovieContext context)
{
_context = context;
}
Zie Asynchrone code voor meer informatie over asynchrone programmering met Entity Framework.
Wanneer er een GET
aanvraag voor de pagina wordt ingediend, retourneert de OnGetAsync
methode een lijst met films naar de Razor pagina. Op een Razor pagina OnGetAsync
of OnGet
wordt aangeroepen om de status van de pagina te initialiseren. In dit geval haalt OnGetAsync
een lijst met films op en geeft deze weer.
Wanneer OnGet
void
teruggeeft of OnGetAsync
Task
teruggeeft, wordt er geen return-statement gebruikt. Bekijk bijvoorbeeld de Privacy pagina:
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace RazorPagesMovie.Pages
{
public class PrivacyModel : PageModel
{
private readonly ILogger<PrivacyModel> _logger;
public PrivacyModel(ILogger<PrivacyModel> logger)
{
_logger = logger;
}
public void OnGet()
{
}
}
}
Wanneer het retourtype IActionResult of Task<IActionResult>
is, moet er een returninstructie worden opgegeven. Bijvoorbeeld de Pages/Movies/Create.cshtml.cs OnPostAsync
methode:
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
_context.Movie.Add(Movie);
await _context.SaveChangesAsync();
return RedirectToPage("./Index");
}
Bekijk de Pages/Movies/Index.cshtml
Razor pagina:
@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 kan worden overgestapt van HTML naar C# of naar Razor-specifieke markeringen. Wanneer een @
symbool wordt gevolgd door een Razor gereserveerd trefwoord, wordt het overgegaan naar Razor-specifieke markeringen, anders wordt het overgegaan naar C#.
De richtlijn @page
De @page
Razor instructie maakt het bestand een MVC-actie, wat betekent dat het aanvragen kan verwerken.
@page
moet de eerste Razor instructie op een pagina zijn.
@page
en @model
zijn voorbeelden van overgang naar Razor-specifieke markeringen. Zie Razor de syntaxis voor meer informatie.
De richtlijn @model
@page
@model RazorPagesMovie.Pages.Movies.IndexModel
De @model
richtlijn geeft het type model aan dat aan de Razor pagina wordt doorgegeven. In het voorgaande voorbeeld maakt de @model
regel de PageModel
afgeleide klasse beschikbaar voor de Razor pagina. Het model wordt gebruikt in de @Html.DisplayNameFor
@Html.DisplayFor
HTML-Helpers op de pagina.
Bekijk de lambda-expressie die wordt gebruikt in de volgende HTML-helper:
@Html.DisplayNameFor(model => model.Movie[0].Title)
De DisplayNameFor HTML Helper inspecteert de Title
eigenschap waarnaar wordt verwezen in de lambda-expressie om de weergavenaam te bepalen. De lambda-expressie wordt geïnspecteerd in plaats van geëvalueerd. Dit betekent dat er geen toegangsschending is wanneer model
, model.Movie
, of model.Movie[0]
null
of leeg is. Wanneer de lambda-expressie wordt geëvalueerd, bijvoorbeeld met @Html.DisplayFor(modelItem => item.Title)
, worden de eigenschapswaarden van het model geëvalueerd.
De indelingspagina
Selecteer de menukoppelingen RazorPagesMovie, Home, en Privacy. Elke pagina bevat dezelfde menu-indeling. De menu-indeling wordt geïmplementeerd in het Pages/Shared/_Layout.cshtml
bestand.
Open het Pages/Shared/_Layout.cshtml
bestand en bekijk het.
Met indelingssjablonen kan de HTML-containerindeling het volgende zijn:
- Gespecificeerd op één plaats.
- Toegepast op meerdere pagina's op de site.
Zoek de @RenderBody()
lijn.
RenderBody
is een tijdelijke aanduiding waarin alle paginaspecifieke weergaven worden weergegeven, verpakt op de indelingspagina. Selecteer bijvoorbeeld de Privacy koppeling en de Pages/Privacy.cshtml
weergave wordt weergegeven in de RenderBody
methode.
Weergavegegevens en layout
Houd rekening met de volgende markeringen uit het Pages/Movies/Index.cshtml
bestand:
@page
@model RazorPagesMovie.Pages.Movies.IndexModel
@{
ViewData["Title"] = "Index";
}
De vooraf gemarkeerde markeringen zijn een voorbeeld van Razor dat overgaat naar C#. De {
tekens en }
bevatten een blok C#-code.
De PageModel
basisklasse bevat een ViewData
woordenlijsteigenschap die kan worden gebruikt om gegevens door te geven aan een weergave. Objecten worden aan de ViewData
woordenlijst toegevoegd met behulp van een sleutelwaardepatroon . In het voorgaande voorbeeld wordt de Title
eigenschap toegevoegd aan de ViewData
woordenlijst.
De Title
eigenschap wordt gebruikt in het Pages/Shared/_Layout.cshtml
bestand. In de volgende markeringen worden de eerste regels van het _Layout.cshtml
bestand weergegeven.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - RazorPagesMovie</title>
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
<link rel="stylesheet" href="~/RazorPagesMovie.styles.css" asp-append-version="true" />
De indeling bijwerken
Wijzig het
<title>
element in hetPages/Shared/_Layout.cshtml
bestand om Film weer te geven in plaats van 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>
Zoek het volgende ankerelement in het
Pages/Shared/_Layout.cshtml
bestand.<a class="navbar-brand" asp-area="" asp-page="/Index">RazorPagesMovie</a>
Vervang het voorgaande element door de volgende markeringen:
<a class="navbar-brand" asp-page="/Movies/Index">RpMovie</a>
Het voorgaande ankerelement is een Tag Helper. In dit geval is het de Anchor Tag Helper. Het
asp-page="/Movies/Index"
Tag Helper-kenmerk en -waarde maken een koppeling naar de/Movies/Index
Razor pagina. Deasp-area
kenmerkwaarde is leeg, dus het gebied wordt niet gebruikt in de koppeling. Zie Gebieden voor meer informatie.Sla de wijzigingen op en test de app door de RpMovie-koppeling te selecteren. Zie het bestand _Layout.cshtml in GitHub als u problemen ondervindt.
Test de koppelingen Home, RpMovie, Maken, Bewerken en Verwijderen. Op elke pagina wordt de titel ingesteld die je in het tabblad van de browser kunt zien. Wanneer je een pagina als bladwijzer opslaat, wordt de titel gebruikt voor de bladwijzer.
Opmerking
Mogelijk kunt u geen decimale komma's invoeren in het veld Price
. Als u jQuery-validatie wilt ondersteunen voor niet-Engelse landinstellingen die een komma (",") gebruiken voor een decimaalteken en niet-US-English datumnotaties, moet u stappen ondernemen om de app te globaliseren. Zie dit GitHub-probleem 4076 voor instructies over het toevoegen van decimale komma's.
De Layout
eigenschap is ingesteld in het Pages/_ViewStart.cshtml
bestand:
@{
Layout = "_Layout";
}
Met de voorgaande opmaak wordt het indelingsbestand ingesteld Pages/Shared/_Layout.cshtml
op alle Razor bestanden onder de map Pagina's . Zie Indeling voor meer informatie.
Het paginamodel maken
Bekijk het Pages/Movies/Create.cshtml.cs
paginamodel:
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using RazorPagesMovie.Models;
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; } = default!;
// To protect from overposting attacks, see https://aka.ms/RazorPagesCRUD
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid || _context.Movie == null || Movie == null)
{
return Page();
}
_context.Movie.Add(Movie);
await _context.SaveChangesAsync();
return RedirectToPage("./Index");
}
}
}
De OnGet
methode initialiseert alle statussen die nodig zijn voor de pagina. De Maakpagina heeft geen status die hoeft te worden geïnitialiseerd, dus Page
wordt geretourneerd. Verderop in de zelfstudie wordt een voorbeeld van OnGet
de initialisatiestatus weergegeven. Met de Page
methode wordt een PageResult
object gemaakt waarmee de Create.cshtml
pagina wordt weergegeven.
De Movie
eigenschap maakt gebruik van het kenmerk [BindProperty] om deel te nemen aan modelbinding. Wanneer het formulier maken de formulierwaarden plaatst, verbindt de ASP.NET Core-runtime de geplaatste waarden aan het Movie
model.
De OnPostAsync
methode wordt uitgevoerd wanneer de formuliergegevens van de pagina worden geplaatst:
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
_context.Movie.Add(Movie);
await _context.SaveChangesAsync();
return RedirectToPage("./Index");
}
Als er modelfouten zijn, wordt het formulier opnieuw weergegeven, samen met eventuele formuliergegevens die zijn gepost. De meeste modelfouten kunnen aan de clientzijde worden opgevangen voordat het formulier wordt geplaatst. Een voorbeeld van een modelfout is het posten van een waarde voor het datumveld dat niet kan worden geconverteerd naar een datum. Validatie aan de clientzijde en modelvalidatie worden verderop in de zelfstudie besproken.
Als er geen modelfouten zijn:
- De gegevens worden opgeslagen.
- De browser wordt omgeleid naar de pagina Index.
De pagina Maken Razor
Bekijk het Pages/Movies/Create.cshtml
Razor paginabestand:
@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 geeft de volgende tags weer in een opvallend vet lettertype dat wordt gebruikt voor 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>
Het <form method="post">
element is een Helper voor formuliertags. De Helper voor formuliertags bevat automatisch een antiforgery-token.
De scaffolding-engine creëert Razor markup voor elk veld in het model, behalve de ID, zoals de volgende:
<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>
In de Helpers voor validatietags (<div asp-validation-summary
en <span asp-validation-for
) worden validatiefouten weergegeven. De validatie wordt verderop in deze reeks uitgebreider besproken.
De Label Tag Helper (<label asp-for="Movie.Title" class="control-label"></label>
) genereert het labelbijschrift en [for]
kenmerk voor de Title
eigenschap.
De Helper voor invoertags (<input asp-for="Movie.Title" class="form-control">
) maakt gebruik van de kenmerken DataAnnotations en produceert HTML-kenmerken die nodig zijn voor jQuery-validatie aan de clientzijde.
Zie <form method="post">
voor meer informatie over Tag Helpers zoals.
Volgende stappen
De pagina's Maken, Verwijderen, Details en Bewerken
Bekijk het Pages/Movies/Index.cshtml.cs
paginamodel:
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using RazorPagesMovie.Models;
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; } = default!;
public async Task OnGetAsync()
{
if (_context.Movie != null)
{
Movie = await _context.Movie.ToListAsync();
}
}
}
Razor Pagina's zijn afgeleid van PageModel. Volgens conventie heeft de afgeleide klasse de PageModel
naam PageNameModel
. De indexpagina heeft bijvoorbeeld de naam IndexModel
.
De constructor gebruikt afhankelijkheidsinjectie om RazorPagesMovieContext
aan de pagina toe te voegen.
public class IndexModel : PageModel
{
private readonly RazorPagesMovie.Data.RazorPagesMovieContext _context;
public IndexModel(RazorPagesMovie.Data.RazorPagesMovieContext context)
{
_context = context;
}
Zie Asynchrone code voor meer informatie over asynchrone programmering met Entity Framework.
Wanneer er een GET
aanvraag voor de pagina wordt ingediend, retourneert de OnGetAsync
methode een lijst met films naar de Razor pagina. Op een Razor pagina OnGetAsync
of OnGet
wordt aangeroepen om de status van de pagina te initialiseren. In dit geval haalt OnGetAsync
een lijst met films op en geeft deze weer.
Wanneer OnGet
void
teruggeeft of OnGetAsync
Task
teruggeeft, wordt er geen return-statement gebruikt. Bekijk bijvoorbeeld de Privacy pagina:
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace RazorPagesMovie.Pages
{
public class PrivacyModel : PageModel
{
private readonly ILogger<PrivacyModel> _logger;
public PrivacyModel(ILogger<PrivacyModel> logger)
{
_logger = logger;
}
public void OnGet()
{
}
}
}
Wanneer het retourtype IActionResult of Task<IActionResult>
is, moet er een returninstructie worden opgegeven. Bijvoorbeeld de Pages/Movies/Create.cshtml.cs OnPostAsync
methode:
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
_context.Movie.Add(Movie);
await _context.SaveChangesAsync();
return RedirectToPage("./Index");
}
Bekijk de Pages/Movies/Index.cshtml
Razor pagina:
@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 kan worden overgestapt van HTML naar C# of naar Razor-specifieke markeringen. Wanneer een @
symbool wordt gevolgd door een Razor gereserveerd trefwoord, wordt het overgegaan naar Razor-specifieke markeringen, anders wordt het overgegaan naar C#.
De richtlijn @page
De @page
Razor instructie maakt het bestand een MVC-actie, wat betekent dat het aanvragen kan verwerken.
@page
moet de eerste Razor instructie op een pagina zijn.
@page
en @model
zijn voorbeelden van overgang naar Razor-specifieke markeringen. Zie Razor de syntaxis voor meer informatie.
De richtlijn @model
@page
@model RazorPagesMovie.Pages.Movies.IndexModel
De @model
richtlijn geeft het type model aan dat aan de Razor pagina wordt doorgegeven. In het voorgaande voorbeeld maakt de @model
regel de PageModel
afgeleide klasse beschikbaar voor de Razor pagina. Het model wordt gebruikt in de @Html.DisplayNameFor
@Html.DisplayFor
HTML-Helpers op de pagina.
Bekijk de lambda-expressie die wordt gebruikt in de volgende HTML-helper:
@Html.DisplayNameFor(model => model.Movie[0].Title)
De DisplayNameFor HTML Helper inspecteert de Title
eigenschap waarnaar wordt verwezen in de lambda-expressie om de weergavenaam te bepalen. De lambda-expressie wordt geïnspecteerd in plaats van geëvalueerd. Dit betekent dat er geen toegangsschending is wanneer model
, model.Movie
, of model.Movie[0]
null
of leeg is. Wanneer de lambda-expressie wordt geëvalueerd, bijvoorbeeld met @Html.DisplayFor(modelItem => item.Title)
, worden de eigenschapswaarden van het model geëvalueerd.
De indelingspagina
Selecteer de menukoppelingen RazorPagesMovie, Home, en Privacy. Elke pagina bevat dezelfde menu-indeling. De menu-indeling wordt geïmplementeerd in het Pages/Shared/_Layout.cshtml
bestand.
Open het Pages/Shared/_Layout.cshtml
bestand en bekijk het.
Met indelingssjablonen kan de HTML-containerindeling het volgende zijn:
- Gespecificeerd op één plaats.
- Toegepast op meerdere pagina's op de site.
Zoek de @RenderBody()
lijn.
RenderBody
is een tijdelijke aanduiding waarin alle paginaspecifieke weergaven worden weergegeven, verpakt op de indelingspagina. Selecteer bijvoorbeeld de Privacy koppeling en de Pages/Privacy.cshtml
weergave wordt weergegeven in de RenderBody
methode.
Weergavegegevens en layout
Houd rekening met de volgende markeringen uit het Pages/Movies/Index.cshtml
bestand:
@page
@model RazorPagesMovie.Pages.Movies.IndexModel
@{
ViewData["Title"] = "Index";
}
De vooraf gemarkeerde markeringen zijn een voorbeeld van Razor dat overgaat naar C#. De {
tekens en }
bevatten een blok C#-code.
De PageModel
basisklasse bevat een ViewData
woordenlijsteigenschap die kan worden gebruikt om gegevens door te geven aan een weergave. Objecten worden aan de ViewData
woordenlijst toegevoegd met behulp van een sleutelwaardepatroon . In het voorgaande voorbeeld wordt de Title
eigenschap toegevoegd aan de ViewData
woordenlijst.
De Title
eigenschap wordt gebruikt in het Pages/Shared/_Layout.cshtml
bestand. In de volgende markeringen worden de eerste regels van het _Layout.cshtml
bestand weergegeven.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - RazorPagesMovie</title>
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
<link rel="stylesheet" href="~/RazorPagesMovie.styles.css" asp-append-version="true" />
De regel @*Markup removed for brevity.*@
is een Razor opmerking. In tegenstelling tot HTML-opmerkingen <!-- -->
worden Razor opmerkingen niet naar de client verzonden. Zie MDN-webdocumenten: Aan de slag met HTML voor meer informatie.
De indeling bijwerken
Wijzig het
<title>
element in hetPages/Shared/_Layout.cshtml
bestand om Film weer te geven in plaats van 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>
Zoek het volgende ankerelement in het
Pages/Shared/_Layout.cshtml
bestand.<a class="navbar-brand" asp-area="" asp-page="/Index">RazorPagesMovie</a>
Vervang het voorgaande element door de volgende markeringen:
<a class="navbar-brand" asp-page="/Movies/Index">RpMovie</a>
Het voorgaande ankerelement is een Tag Helper. In dit geval is het de Anchor Tag Helper. Het
asp-page="/Movies/Index"
Tag Helper-kenmerk en -waarde maken een koppeling naar de/Movies/Index
Razor pagina. Deasp-area
kenmerkwaarde is leeg, dus het gebied wordt niet gebruikt in de koppeling. Zie Gebieden voor meer informatie.Sla de wijzigingen op en test de app door de RpMovie-koppeling te selecteren. Zie het bestand _Layout.cshtml in GitHub als u problemen ondervindt.
Test de koppelingen Home, RpMovie, Maken, Bewerken en Verwijderen. Op elke pagina wordt de titel ingesteld die je in het tabblad van de browser kunt zien. Wanneer je een pagina als bladwijzer opslaat, wordt de titel gebruikt voor de bladwijzer.
Opmerking
Mogelijk kunt u geen decimale komma's invoeren in het veld Price
. Als u jQuery-validatie wilt ondersteunen voor niet-Engelse landinstellingen die een komma (",") gebruiken voor een decimaalteken en niet-US-English datumnotaties, moet u stappen ondernemen om de app te globaliseren. Zie dit GitHub-probleem 4076 voor instructies over het toevoegen van decimale komma's.
De Layout
eigenschap is ingesteld in het Pages/_ViewStart.cshtml
bestand:
@{
Layout = "_Layout";
}
Met de voorgaande opmaak wordt het indelingsbestand ingesteld Pages/Shared/_Layout.cshtml
op alle Razor bestanden onder de map Pagina's . Zie Indeling voor meer informatie.
Het paginamodel maken
Bekijk het Pages/Movies/Create.cshtml.cs
paginamodel:
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using RazorPagesMovie.Models;
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; } = default!;
// To protect from overposting attacks, see https://aka.ms/RazorPagesCRUD
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid || _context.Movie == null || Movie == null)
{
return Page();
}
_context.Movie.Add(Movie);
await _context.SaveChangesAsync();
return RedirectToPage("./Index");
}
}
}
De OnGet
methode initialiseert alle statussen die nodig zijn voor de pagina. De Maakpagina heeft geen status die hoeft te worden geïnitialiseerd, dus Page
wordt geretourneerd. Verderop in de zelfstudie wordt een voorbeeld van OnGet
de initialisatiestatus weergegeven. Met de Page
methode wordt een PageResult
object gemaakt waarmee de Create.cshtml
pagina wordt weergegeven.
De Movie
eigenschap maakt gebruik van het kenmerk [BindProperty] om deel te nemen aan modelbinding. Wanneer het formulier maken de formulierwaarden plaatst, verbindt de ASP.NET Core-runtime de geplaatste waarden aan het Movie
model.
De OnPostAsync
methode wordt uitgevoerd wanneer de formuliergegevens van de pagina worden geplaatst:
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
_context.Movie.Add(Movie);
await _context.SaveChangesAsync();
return RedirectToPage("./Index");
}
Als er modelfouten zijn, wordt het formulier opnieuw weergegeven, samen met eventuele formuliergegevens die zijn gepost. De meeste modelfouten kunnen aan de clientzijde worden opgevangen voordat het formulier wordt geplaatst. Een voorbeeld van een modelfout is het posten van een waarde voor het datumveld dat niet kan worden geconverteerd naar een datum. Validatie aan de clientzijde en modelvalidatie worden verderop in de zelfstudie besproken.
Als er geen modelfouten zijn:
- De gegevens worden opgeslagen.
- De browser wordt omgeleid naar de pagina Index.
De pagina Maken Razor
Bekijk het Pages/Movies/Create.cshtml
Razor paginabestand:
@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 geeft de volgende tags weer in een opvallend vet lettertype dat wordt gebruikt voor 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>
Het <form method="post">
element is een Helper voor formuliertags. De Helper voor formuliertags bevat automatisch een antiforgery-token.
De scaffolding-engine creëert Razor markup voor elk veld in het model, behalve de ID, zoals de volgende:
<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>
In de Helpers voor validatietags (<div asp-validation-summary
en <span asp-validation-for
) worden validatiefouten weergegeven. De validatie wordt verderop in deze reeks uitgebreider besproken.
De Label Tag Helper (<label asp-for="Movie.Title" class="control-label"></label>
) genereert het labelbijschrift en [for]
kenmerk voor de Title
eigenschap.
De Helper voor invoertags (<input asp-for="Movie.Title" class="form-control">
) maakt gebruik van de kenmerken DataAnnotations en produceert HTML-kenmerken die nodig zijn voor jQuery-validatie aan de clientzijde.
Zie <form method="post">
voor meer informatie over Tag Helpers zoals.
Volgende stappen
De pagina's Maken, Verwijderen, Details en Bewerken
Bekijk het Pages/Movies/Index.cshtml.cs
paginamodel:
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using RazorPagesMovie.Models;
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; } = default!;
public async Task OnGetAsync()
{
if (_context.Movie != null)
{
Movie = await _context.Movie.ToListAsync();
}
}
}
}
Razor Pagina's zijn afgeleid van PageModel. Volgens conventie heeft de afgeleide klasse de PageModel
naam PageNameModel
. De indexpagina heeft bijvoorbeeld de naam IndexModel
.
De constructor gebruikt afhankelijkheidsinjectie om RazorPagesMovieContext
aan de pagina toe te voegen.
public class IndexModel : PageModel
{
private readonly RazorPagesMovie.Data.RazorPagesMovieContext _context;
public IndexModel(RazorPagesMovie.Data.RazorPagesMovieContext context)
{
_context = context;
}
Zie Asynchrone code voor meer informatie over asynchrone programmering met Entity Framework.
Wanneer er een aanvraag voor de pagina wordt ingediend, retourneert de OnGetAsync
methode een lijst met films naar de Razor pagina. Op een Razor pagina OnGetAsync
of OnGet
wordt aangeroepen om de status van de pagina te initialiseren. In dit geval haalt OnGetAsync
een lijst met films op en geeft deze weer.
Wanneer OnGet
void
teruggeeft of OnGetAsync
Task
teruggeeft, wordt er geen return-statement gebruikt. Bekijk bijvoorbeeld de Privacy pagina:
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace RazorPagesMovie.Pages
{
public class PrivacyModel : PageModel
{
private readonly ILogger<PrivacyModel> _logger;
public PrivacyModel(ILogger<PrivacyModel> logger)
{
_logger = logger;
}
public void OnGet()
{
}
}
}
Wanneer het retourtype IActionResult of Task<IActionResult>
is, moet er een returninstructie worden opgegeven. Bijvoorbeeld de Pages/Movies/Create.cshtml.cs
OnPostAsync
methode:
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid || _context.Movie == null || Movie == null)
{
return Page();
}
_context.Movie.Add(Movie);
await _context.SaveChangesAsync();
return RedirectToPage("./Index");
}
Bekijk de Pages/Movies/Index.cshtml
Razor pagina:
@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 kan worden overgestapt van HTML naar C# of naar Razor-specifieke markeringen. Wanneer een @
symbool wordt gevolgd door een Razor gereserveerd trefwoord, wordt het overgegaan naar Razor-specifieke markeringen, anders wordt het overgegaan naar C#.
De richtlijn @page
De @page
Razor instructie maakt het bestand een MVC-actie, wat betekent dat het aanvragen kan verwerken.
@page
moet de eerste Razor instructie op een pagina zijn.
@page
en @model
zijn voorbeelden van overgang naar Razor-specifieke markeringen. Zie Razor de syntaxis voor meer informatie.
De richtlijn @model
@page
@model RazorPagesMovie.Pages.Movies.IndexModel
De @model
richtlijn geeft het type model aan dat aan de Razor pagina wordt doorgegeven. In het voorgaande voorbeeld maakt de @model
regel de PageModel
afgeleide klasse beschikbaar voor de Razor pagina. Het model wordt gebruikt in de @Html.DisplayNameFor
@Html.DisplayFor
HTML-Helpers op de pagina.
Bekijk de lambda-expressie die wordt gebruikt in de volgende HTML-helper:
@Html.DisplayNameFor(model => model.Movie[0].Title)
De DisplayNameFor HTML Helper inspecteert de Title
eigenschap waarnaar wordt verwezen in de lambda-expressie om de weergavenaam te bepalen. De lambda-expressie wordt geïnspecteerd in plaats van geëvalueerd. Dit betekent dat er geen toegangsschending is wanneer model
, model.Movie
, of model.Movie[0]
null
of leeg is. Wanneer de lambda-expressie wordt geëvalueerd, bijvoorbeeld met @Html.DisplayFor(modelItem => item.Title)
, worden de eigenschapswaarden van het model geëvalueerd.
De indelingspagina
Selecteer de menukoppelingen RazorPagesMovie, Home, en Privacy. Elke pagina bevat dezelfde menu-indeling. De menu-indeling wordt geïmplementeerd in het Pages/Shared/_Layout.cshtml
bestand.
Open het Pages/Shared/_Layout.cshtml
bestand en bekijk het.
Met indelingssjablonen kan de HTML-containerindeling het volgende zijn:
- Gespecificeerd op één plaats.
- Toegepast op meerdere pagina's op de site.
Zoek de @RenderBody()
lijn.
RenderBody
is een tijdelijke aanduiding waarin alle paginaspecifieke weergaven worden weergegeven, verpakt op de indelingspagina. Selecteer bijvoorbeeld de Privacy koppeling en de Pages/Privacy.cshtml
weergave wordt weergegeven in de RenderBody
methode.
Weergavegegevens en layout
Houd rekening met de volgende markeringen uit het Pages/Movies/Index.cshtml
bestand:
@page
@model RazorPagesMovie.Pages.Movies.IndexModel
@{
ViewData["Title"] = "Index";
}
De vooraf gemarkeerde markeringen zijn een voorbeeld van Razor dat overgaat naar C#. De {
tekens en }
bevatten een blok C#-code.
De PageModel
basisklasse bevat een ViewData
woordenlijsteigenschap die kan worden gebruikt om gegevens door te geven aan een weergave. Objecten worden aan de ViewData
woordenlijst toegevoegd met behulp van een sleutelwaardepatroon . In het voorgaande voorbeeld wordt de Title
eigenschap toegevoegd aan de ViewData
woordenlijst.
De Title
eigenschap wordt gebruikt in het Pages/Shared/_Layout.cshtml
bestand. In de volgende markeringen worden de eerste regels van het _Layout.cshtml
bestand weergegeven.
<!DOCTYPE html>
<html lang="en">
<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.*@
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
De regel @*Markup removed for brevity.*@
is een Razor opmerking. In tegenstelling tot HTML-opmerkingen <!-- -->
worden Razor opmerkingen niet naar de client verzonden. Zie MDN-webdocumenten: Aan de slag met HTML voor meer informatie.
De indeling bijwerken
Wijzig het
<title>
element in hetPages/Shared/_Layout.cshtml
bestand om Film weer te geven in plaats van 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>
Zoek het volgende ankerelement in het
Pages/Shared/_Layout.cshtml
bestand.<a class="navbar-brand" asp-area="" asp-page="/Index">RazorPagesMovie</a>
Vervang het voorgaande element door de volgende markeringen:
<a class="navbar-brand" asp-page="/Movies/Index">RpMovie</a>
Het voorgaande ankerelement is een Tag Helper. In dit geval is het de Anchor Tag Helper. Het
asp-page="/Movies/Index"
Tag Helper-kenmerk en -waarde maken een koppeling naar de/Movies/Index
Razor pagina. Deasp-area
kenmerkwaarde is leeg, dus het gebied wordt niet gebruikt in de koppeling. Zie Gebieden voor meer informatie.Sla de wijzigingen op en test de app door de RpMovie-koppeling te selecteren. Zie het bestand _Layout.cshtml in GitHub als u problemen ondervindt.
Test de koppelingen Home, RpMovie, Maken, Bewerken en Verwijderen. Op elke pagina wordt de titel ingesteld die je in het tabblad van de browser kunt zien. Wanneer je een pagina als bladwijzer opslaat, wordt de titel gebruikt voor de bladwijzer.
Opmerking
Mogelijk kunt u geen decimale komma's invoeren in het veld Price
. Als u jQuery-validatie wilt ondersteunen voor niet-Engelse landinstellingen die een komma (",") gebruiken voor een decimaalteken en niet-US-English datumnotaties, moet u stappen ondernemen om de app te globaliseren. Zie dit GitHub-probleem 4076 voor instructies over het toevoegen van decimale komma's.
De Layout
eigenschap is ingesteld in het Pages/_ViewStart.cshtml
bestand:
@{
Layout = "_Layout";
}
Met de voorgaande opmaak wordt het indelingsbestand ingesteld Pages/Shared/_Layout.cshtml
op alle Razor bestanden onder de map Pagina's . Zie Indeling voor meer informatie.
Het paginamodel maken
Bekijk het Pages/Movies/Create.cshtml.cs
paginamodel:
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using RazorPagesMovie.Models;
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; } = default!;
// To protect from overposting attacks, see https://aka.ms/RazorPagesCRUD
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid || _context.Movie == null || Movie == null)
{
return Page();
}
_context.Movie.Add(Movie);
await _context.SaveChangesAsync();
return RedirectToPage("./Index");
}
}
}
De OnGet
methode initialiseert alle statussen die nodig zijn voor de pagina. De Maakpagina heeft geen status die hoeft te worden geïnitialiseerd, dus Page
wordt geretourneerd. Verderop in de zelfstudie wordt een voorbeeld van OnGet
de initialisatiestatus weergegeven. Met de Page
methode wordt een PageResult
object gemaakt waarmee de Create.cshtml
pagina wordt weergegeven.
De Movie
eigenschap maakt gebruik van het kenmerk [BindProperty] om deel te nemen aan modelbinding. Wanneer het formulier maken de formulierwaarden plaatst, verbindt de ASP.NET Core-runtime de geplaatste waarden aan het Movie
model.
De OnPostAsync
methode wordt uitgevoerd wanneer de formuliergegevens van de pagina worden geplaatst:
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid || _context.Movie == null || Movie == null)
{
return Page();
}
_context.Movie.Add(Movie);
await _context.SaveChangesAsync();
return RedirectToPage("./Index");
}
Als er modelfouten zijn, wordt het formulier opnieuw weergegeven, samen met eventuele formuliergegevens die zijn gepost. De meeste modelfouten kunnen aan de clientzijde worden opgevangen voordat het formulier wordt geplaatst. Een voorbeeld van een modelfout is het posten van een waarde voor het datumveld dat niet kan worden geconverteerd naar een datum. Validatie aan de clientzijde en modelvalidatie worden verderop in de zelfstudie besproken.
Als er geen modelfouten zijn:
- De gegevens worden opgeslagen.
- De browser wordt omgeleid naar de pagina Index.
De pagina Maken Razor
Bekijk het Pages/Movies/Create.cshtml
Razor paginabestand:
@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 geeft de volgende tags weer in een opvallend vet lettertype dat wordt gebruikt voor 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>
Het <form method="post">
element is een Helper voor formuliertags. De Helper voor formuliertags bevat automatisch een antiforgery-token.
De scaffolding-engine creëert Razor markup voor elk veld in het model, behalve de ID, zoals de volgende:
<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>
In de Helpers voor validatietags (<div asp-validation-summary
en <span asp-validation-for
) worden validatiefouten weergegeven. De validatie wordt verderop in deze reeks uitgebreider besproken.
De Label Tag Helper (<label asp-for="Movie.Title" class="control-label"></label>
) genereert het labelbijschrift en [for]
kenmerk voor de Title
eigenschap.
De Helper voor invoertags (<input asp-for="Movie.Title" class="form-control">
) maakt gebruik van de kenmerken DataAnnotations en produceert HTML-kenmerken die nodig zijn voor jQuery-validatie aan de clientzijde.
Zie <form method="post">
voor meer informatie over Tag Helpers zoals.
Volgende stappen
De pagina's Maken, Verwijderen, Details en Bewerken
Bekijk het Pages/Movies/Index.cshtml.cs
paginamodel:
// 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();
}
}
}
Razor Pagina's zijn afgeleid van PageModel
. Volgens conventie wordt de PageModel
-afgeleide klasse <PageName>Model
genoemd. De constructor gebruikt afhankelijkheidsinjectie om RazorPagesMovieContext
aan de pagina toe te voegen.
public class IndexModel : PageModel
{
private readonly RazorPagesMovie.Data.RazorPagesMovieContext _context;
public IndexModel(RazorPagesMovie.Data.RazorPagesMovieContext context)
{
_context = context;
}
Zie Asynchrone code voor meer informatie over asynchrone programmering met Entity Framework.
Wanneer er een aanvraag voor de pagina wordt ingediend, retourneert de OnGetAsync
methode een lijst met films naar de Razor pagina. Op een Razor pagina OnGetAsync
of OnGet
wordt aangeroepen om de status van de pagina te initialiseren. In dit geval haalt OnGetAsync
een lijst met films op en geeft deze weer.
Wanneer OnGet
void
teruggeeft of OnGetAsync
Task
teruggeeft, wordt er geen return-statement gebruikt. Bijvoorbeeld de Privacy pagina:
public class PrivacyModel : PageModel
{
private readonly ILogger<PrivacyModel> _logger;
public PrivacyModel(ILogger<PrivacyModel> logger)
{
_logger = logger;
}
public void OnGet()
{
}
}
Wanneer het retourtype IActionResult
of Task<IActionResult>
is, moet er een returninstructie worden opgegeven. Bijvoorbeeld de Pages/Movies/Create.cshtml.cs
OnPostAsync
methode:
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
_context.Movie.Add(Movie);
await _context.SaveChangesAsync();
return RedirectToPage("./Index");
}
}
Bekijk de Pages/Movies/Index.cshtml
Razor pagina:
@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 kan worden overgestapt van HTML naar C# of naar Razor-specifieke markeringen. Wanneer een @
symbool wordt gevolgd door een Razor gereserveerd trefwoord, wordt het overgegaan naar Razor-specifieke markeringen, anders wordt het overgegaan naar C#.
De richtlijn @page
De @page
Razor instructie maakt het bestand een MVC-actie, wat betekent dat het aanvragen kan verwerken.
@page
moet de eerste Razor instructie op een pagina zijn.
@page
en @model
zijn voorbeelden van overgang naar Razor-specifieke markeringen. Zie Razor de syntaxis voor meer informatie.
De richtlijn @model
@page
@model RazorPagesMovie.Pages.Movies.IndexModel
De @model
richtlijn geeft het type model aan dat aan de Razor pagina wordt doorgegeven. In het voorgaande voorbeeld maakt de @model
regel de afgeleide PageModel
-klasse beschikbaar voor de Razor pagina. Het model wordt gebruikt in de @Html.DisplayNameFor
@Html.DisplayFor
HTML-Helpers op de pagina.
Bekijk de lambda-expressie die wordt gebruikt in de volgende HTML-helper:
@Html.DisplayNameFor(model => model.Movie[0].Title)
De DisplayNameFor HTML Helper inspecteert de Title
eigenschap waarnaar wordt verwezen in de lambda-expressie om de weergavenaam te bepalen. De lambda-expressie wordt geïnspecteerd in plaats van geëvalueerd. Dit betekent dat er geen toegangsschending is wanneer model
, model.Movie
, of model.Movie[0]
null
of leeg is. Wanneer de lambda-expressie wordt geëvalueerd, bijvoorbeeld met @Html.DisplayFor(modelItem => item.Title)
, worden de eigenschapswaarden van het model geëvalueerd.
De indelingspagina
Selecteer de menukoppelingen RazorPagesMovie, Home, en Privacy. Elke pagina bevat dezelfde menu-indeling. De menu-indeling wordt geïmplementeerd in het Pages/Shared/_Layout.cshtml
bestand.
Open het Pages/Shared/_Layout.cshtml
bestand en bekijk het.
Met indelingssjablonen kan de HTML-containerindeling het volgende zijn:
- Gespecificeerd op één plaats.
- Toegepast op meerdere pagina's op de site.
Zoek de @RenderBody()
lijn.
RenderBody
is een tijdelijke aanduiding waarin alle paginaspecifieke weergaven worden weergegeven, verpakt op de indelingspagina. Selecteer bijvoorbeeld de Privacy koppeling en de Pages/Privacy.cshtml
weergave wordt weergegeven in de RenderBody
methode.
Weergavegegevens en layout
Houd rekening met de volgende markeringen uit het Pages/Movies/Index.cshtml
bestand:
@page
@model RazorPagesMovie.Pages.Movies.IndexModel
@{
ViewData["Title"] = "Index";
}
De vooraf gemarkeerde markeringen zijn een voorbeeld van Razor dat overgaat naar C#. De {
tekens en }
bevatten een blok C#-code.
De PageModel
basisklasse bevat een ViewData
woordenlijsteigenschap die kan worden gebruikt om gegevens door te geven aan een weergave. Objecten worden aan de ViewData
woordenlijst toegevoegd met behulp van een sleutelwaardepatroon . In het voorgaande voorbeeld wordt de Title
eigenschap toegevoegd aan de ViewData
woordenlijst.
De Title
eigenschap wordt gebruikt in het Pages/Shared/_Layout.cshtml
bestand. In de volgende markeringen worden de eerste regels van het _Layout.cshtml
bestand weergegeven.
<!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.*@
De regel @*Markup removed for brevity.*@
is een Razor opmerking. In tegenstelling tot HTML-opmerkingen <!-- -->
worden Razor opmerkingen niet naar de client verzonden. Zie MDN-webdocumenten: Aan de slag met HTML voor meer informatie.
De indeling bijwerken
Wijzig het
<title>
element in hetPages/Shared/_Layout.cshtml
bestand om Film weer te geven in plaats van 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>
Zoek het volgende ankerelement in het
Pages/Shared/_Layout.cshtml
bestand.<a class="navbar-brand" asp-area="" asp-page="/Index">RazorPagesMovie</a>
Vervang het voorgaande element door de volgende markeringen:
<a class="navbar-brand" asp-page="/Movies/Index">RpMovie</a>
Het voorgaande ankerelement is een Tag Helper. In dit geval is het de Anchor Tag Helper. Het
asp-page="/Movies/Index"
Tag Helper-kenmerk en -waarde maken een koppeling naar de/Movies/Index
Razor pagina. Deasp-area
kenmerkwaarde is leeg, dus het gebied wordt niet gebruikt in de koppeling. Zie Gebieden voor meer informatie.Sla de wijzigingen op en test de app door de RpMovie-koppeling te selecteren. Zie het bestand _Layout.cshtml in GitHub als u problemen ondervindt.
Test de koppelingen Home, RpMovie, Maken, Bewerken en Verwijderen. Op elke pagina wordt de titel ingesteld die je in het tabblad van de browser kunt zien. Wanneer je een pagina als bladwijzer opslaat, wordt de titel gebruikt voor de bladwijzer.
Opmerking
Mogelijk kunt u geen decimale komma's invoeren in het veld Price
. Als u jQuery-validatie wilt ondersteunen voor niet-Engelse landinstellingen die een komma (",") gebruiken voor een decimaalteken en niet-US-English datumnotaties, moet u stappen ondernemen om de app te globaliseren. Zie dit GitHub-probleem 4076 voor instructies over het toevoegen van decimale komma's.
De Layout
eigenschap is ingesteld in het Pages/_ViewStart.cshtml
bestand:
@{
Layout = "_Layout";
}
Met de voorgaande opmaak wordt het indelingsbestand ingesteld Pages/Shared/_Layout.cshtml
op alle Razor bestanden onder de map Pagina's . Zie Indeling voor meer informatie.
Het paginamodel maken
Bekijk het Pages/Movies/Create.cshtml.cs
paginamodel:
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");
}
}
}
De OnGet
methode initialiseert alle statussen die nodig zijn voor de pagina. De Maakpagina heeft geen status die hoeft te worden geïnitialiseerd, dus Page
wordt geretourneerd. Verderop in de zelfstudie wordt een voorbeeld van OnGet
de initialisatiestatus weergegeven. Met de Page
methode wordt een PageResult
object gemaakt waarmee de Create.cshtml
pagina wordt weergegeven.
De Movie
eigenschap maakt gebruik van het kenmerk [BindProperty] om deel te nemen aan modelbinding. Wanneer het formulier maken de formulierwaarden plaatst, verbindt de ASP.NET Core-runtime de geplaatste waarden aan het Movie
model.
De OnPostAsync
methode wordt uitgevoerd wanneer de formuliergegevens van de pagina worden geplaatst:
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
_context.Movie.Add(Movie);
await _context.SaveChangesAsync();
return RedirectToPage("./Index");
}
Als er modelfouten zijn, wordt het formulier opnieuw weergegeven, samen met eventuele formuliergegevens die zijn gepost. De meeste modelfouten kunnen aan de clientzijde worden opgevangen voordat het formulier wordt geplaatst. Een voorbeeld van een modelfout is het posten van een waarde voor het datumveld dat niet kan worden geconverteerd naar een datum. Validatie aan de clientzijde en modelvalidatie worden verderop in de zelfstudie besproken.
Als er geen modelfouten zijn:
- De gegevens worden opgeslagen.
- De browser wordt omgeleid naar de pagina Index.
De pagina Maken Razor
Bekijk het Pages/Movies/Create.cshtml
Razor paginabestand:
@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 geeft de volgende tags weer in een opvallend vet lettertype dat wordt gebruikt voor 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>
Het <form method="post">
element is een Helper voor formuliertags. De Helper voor formuliertags bevat automatisch een antiforgery-token.
De scaffolding-engine creëert Razor markup voor elk veld in het model, behalve de ID, zoals de volgende:
<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>
In de Helpers voor validatietags (<div asp-validation-summary
en <span asp-validation-for
) worden validatiefouten weergegeven. De validatie wordt verderop in deze reeks uitgebreider besproken.
De Label Tag Helper (<label asp-for="Movie.Title" class="control-label"></label>
) genereert het labelbijschrift en [for]
kenmerk voor de Title
eigenschap.
De Helper voor invoertags (<input asp-for="Movie.Title" class="form-control">
) maakt gebruik van de kenmerken DataAnnotations en produceert HTML-kenmerken die nodig zijn voor jQuery-validatie aan de clientzijde.
Zie <form method="post">
voor meer informatie over Tag Helpers zoals.