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 10-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 10-versie van dit artikel voor de huidige release.
De scaffolded film-app is een goed begin, maar de presentatie is niet ideaal. ReleaseDatum moet twee woorden zijn: Releasedatum.
Het model bijwerken
Werk Models/Movie.cs bij met de volgende gemarkeerde code:
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace RazorPagesMovie.Models;
public class Movie
{
public int Id { get; set; }
public string Title { get; set; } = string.Empty;
[Display(Name = "Release Date")]
[DataType(DataType.Date)]
public DateTime ReleaseDate { get; set; }
public string Genre { get; set; } = string.Empty;
[Column(TypeName = "decimal(18, 2)")]
public decimal Price { get; set; }
}
In de vorige code:
- Met de
[Column(TypeName = "decimal(18, 2)")]gegevensaantekening kan Entity Framework CorePricecorrect toewijzen aan valuta in de database. Zie gegevenstypenvoor meer informatie. - Het kenmerk [Weergave] geeft de weergavenaam van een veld op. In de voorgaande code,
Release Datein plaats vanReleaseDate. - Het kenmerk [DataType] geeft het type van de gegevens (
Date). De tijdgegevens die in het veld zijn opgeslagen, worden niet weergegeven.
DataAnnotations wordt behandeld in de volgende zelfstudie.
Blader naar Pagina's/Films en beweeg de muisaanwijzer over een koppeling Bewerken om de doel-URL te bekijken.
De koppelingen Bewerken, Details en Verwijderen worden gegenereerd door de Anchor Tag Helper in het Pages/Movies/Index.cshtml bestand.
@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>
Tag Helpers zorgen ervoor dat code aan de serverzijde kan deelnemen aan het maken en weergeven van HTML-elementen in Razor bestanden.
In de voorgaande code genereert de Anchor Tag Helper dynamisch de HTML-kenmerkwaarde href van de Razor pagina (de route is relatief), de asp-pageen de route-id (asp-route-id). Zie URL-generatie voor pagina's voor meer informatie.
Gebruik De weergavebron vanuit een browser om de gegenereerde markeringen te onderzoeken. Hieronder ziet u een deel van de gegenereerde HTML:
<td>
<a href="/Movies/Edit?id=1">Edit</a> |
<a href="/Movies/Details?id=1">Details</a> |
<a href="/Movies/Delete?id=1">Delete</a>
</td>
De dynamisch gegenereerde koppelingen geven de film-id door aan een queryreeks. Bijvoorbeeld de ?id=1 in https://localhost:7247/Movies/Details?id=1.
Routesjabloon toevoegen
Pas de pagina's Bewerken, Details en Verwijderen Razor aan om de {id:int} routesjabloon te gebruiken. Wijzig de pagina-instructie voor elk van deze pagina's van @page in @page "{id:int}". Voer de app uit en bekijk vervolgens de bron.
De gegenereerde HTML voegt de ID toe aan het padgedeelte van de URL.
<td>
<a href="/Movies/Edit/1">Edit</a> |
<a href="/Movies/Details/1">Details</a> |
<a href="/Movies/Delete/1">Delete</a>
</td>
Een aanvraag voor de pagina met de {id:int} routesjabloon die niet het gehele getal bevat, retourneert een HTTP 404-fout (niet gevonden). Retourneert bijvoorbeeld https://localhost:7247/Movies/Details een 404-fout. Als u de id optioneel wilt maken, voegt u deze toe aan ? de routebeperking:
@page "{id:int?}"
Test het gedrag van @page "{id:int?}":
- Stel de pagina-richtlijn in
Pages/Movies/Details.cshtmlop@page "{id:int?}". - Stel een onderbrekingspunt in
public async Task<IActionResult> OnGetAsync(int? id), inPages/Movies/Details.cshtml.cs. - Navigeer naar
https://localhost:7247/Movies/Details/.
Met de @page "{id:int}" richtlijn wordt het onderbrekingspunt nooit bereikt. De routeringsengine retourneert HTTP 404.
@page "{id:int?}" De OnGetAsyncmethode retourneert NotFound (HTTP 404):
public async Task<IActionResult> OnGetAsync(int? id)
{
if (id == null)
{
return NotFound();
}
var movie = await _context.Movie.FirstOrDefaultAsync(m => m.Id == id);
if (movie == null)
{
return NotFound();
}
else
{
Movie = movie;
}
return Page();
}
Afhandeling van gelijktijdigheidsonderzondering controleren
Controleer de OnPostAsync methode in het Pages/Movies/Edit.cshtml.cs bestand:
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
_context.Attach(Movie).State = EntityState.Modified;
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!MovieExists(Movie.Id))
{
return NotFound();
}
else
{
throw;
}
}
return RedirectToPage("./Index");
}
private bool MovieExists(int id)
{
return _context.Movie.Any(e => e.Id == id);
}
Met de vorige code worden gelijktijdigheidsonderingen gedetecteerd wanneer de ene client de film verwijdert en de andere client wijzigingen in de film plaatst.
Het catch-blok testen:
- Stel een onderbrekingspunt in op
catch (DbUpdateConcurrencyException). - Selecteer Bewerken voor een film, breng wijzigingen aan, maar selecteer Opslaan niet.
- Selecteer in een ander browservenster de koppeling Verwijderen voor dezelfde film en verwijder de film.
- In het vorige browservenster plaatst u wijzigingen in de film.
Productiecode zou gelijktijdigheidsconflicten kunnen detecteren. Voor meer informatie, zie Gelijktijdigheidsconflicten afhandelen.
Boekings- en bindingsbeoordeling
Bekijk het Pages/Movies/Edit.cshtml.cs bestand:
public class EditModel : PageModel
{
private readonly RazorPagesMovie.Data.RazorPagesMovieContext _context;
public EditModel(RazorPagesMovie.Data.RazorPagesMovieContext context)
{
_context = context;
}
[BindProperty]
public Movie Movie { get; set; } = default!;
public async Task<IActionResult> OnGetAsync(int? id)
{
if (id == null)
{
return NotFound();
}
var movie = await _context.Movie.FirstOrDefaultAsync(m => m.Id == id);
if (movie == null)
{
return NotFound();
}
Movie = movie;
return Page();
}
// To protect from overposting attacks, enable the specific properties you want to bind to.
// For more details, see https://aka.ms/RazorPagesCRUD.
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
_context.Attach(Movie).State = EntityState.Modified;
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!MovieExists(Movie.Id))
{
return NotFound();
}
else
{
throw;
}
}
return RedirectToPage("./Index");
}
private bool MovieExists(int id)
{
return _context.Movie.Any(e => e.Id == id);
}
Wanneer u een HTTP GET-aanvraag naar de Movies/Edit pagina maakt, https://localhost:7247/Movies/Edit/3bijvoorbeeld:
- De
OnGetAsyncmethode haalt de film op uit de database en retourneert dePagemethode. - De
Pagemethode geeft dePages/Movies/Edit.cshtmlRazor pagina weer. HetPages/Movies/Edit.cshtmlbestand bevat de modelrichtlijn@model RazorPagesMovie.Pages.Movies.EditModel, waardoor het filmmodel beschikbaar is op de pagina. - In het formulier Bewerken worden de waarden uit de film weergegeven.
Wanneer u de Movies/Edit pagina plaatst:
De formulierwaarden op de pagina binden aan de
Movieeigenschap. Het[BindProperty]kenmerk maakt modelbinding mogelijk.[BindProperty] public Movie Movie { get; set; }Als er bijvoorbeeld fouten in de modelstatus optreden, zoals dat
ReleaseDateniet kan worden omgezet naar een datum, wordt het formulier opnieuw getoond met de ingediende waarden.Als er geen modelfouten zijn, wordt de film opgeslagen.
De HTTP GET-methoden in de pagina's Index, Maken en Verwijderen Razor volgen een vergelijkbaar patroon. De HTTP POST-methode OnPostAsync in de create Razor page volgt een vergelijkbaar patroon als de OnPostAsync methode in de bewerkingspagina Razor .
Volgende stappen
De opgebouwde filmapplicatie heeft een goed begin, maar de presentatie is niet ideaal. ReleaseDatum moet twee woorden zijn: Releasedatum.
Het model bijwerken
Werk Models/Movie.cs bij met de volgende gemarkeerde code:
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace RazorPagesMovie.Models;
public class Movie
{
public int Id { get; set; }
public string Title { get; set; } = string.Empty;
[Display(Name = "Release Date")]
[DataType(DataType.Date)]
public DateTime ReleaseDate { get; set; }
public string Genre { get; set; } = string.Empty;
[Column(TypeName = "decimal(18, 2)")]
public decimal Price { get; set; }
}
In de vorige code:
- Met de
[Column(TypeName = "decimal(18, 2)")]gegevensaantekening kan Entity Framework CorePricecorrect toewijzen aan valuta in de database. Zie gegevenstypenvoor meer informatie. - Het kenmerk [Weergave] geeft de weergavenaam van een veld op. In de voorgaande code,
Release Datein plaats vanReleaseDate. - Het kenmerk [DataType] geeft het type van de gegevens (
Date). De tijdgegevens die in het veld zijn opgeslagen, worden niet weergegeven.
DataAnnotations wordt behandeld in de volgende zelfstudie.
Blader naar Pagina's/Films en beweeg de muisaanwijzer over een koppeling Bewerken om de doel-URL te bekijken.
De koppelingen Bewerken, Details en Verwijderen worden gegenereerd door de Anchor Tag Helper in het Pages/Movies/Index.cshtml bestand.
@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>
Tag Helpers zorgen ervoor dat code aan de serverzijde kan deelnemen aan het maken en weergeven van HTML-elementen in Razor bestanden.
In de voorgaande code genereert de Anchor Tag Helper dynamisch de HTML-kenmerkwaarde href van de Razor pagina (de route is relatief), de asp-pageen de route-id (asp-route-id). Zie URL-generatie voor pagina's voor meer informatie.
Gebruik De weergavebron vanuit een browser om de gegenereerde markeringen te onderzoeken. Hieronder ziet u een deel van de gegenereerde HTML:
<td>
<a href="/Movies/Edit?id=1">Edit</a> |
<a href="/Movies/Details?id=1">Details</a> |
<a href="/Movies/Delete?id=1">Delete</a>
</td>
De dynamisch gegenereerde koppelingen geven de film-id door aan een queryreeks. Bijvoorbeeld de ?id=1 in https://localhost:5001/Movies/Details?id=1.
Routesjabloon toevoegen
Pas de pagina's Bewerken, Details en Verwijderen Razor aan om de {id:int} routesjabloon te gebruiken. Wijzig de pagina-instructie voor elk van deze pagina's van @page in @page "{id:int}". Voer de app uit en bekijk vervolgens de bron.
De gegenereerde HTML voegt de ID toe aan het padgedeelte van de URL.
<td>
<a href="/Movies/Edit/1">Edit</a> |
<a href="/Movies/Details/1">Details</a> |
<a href="/Movies/Delete/1">Delete</a>
</td>
Een aanvraag naar de pagina met de {id:int} routesjabloon die niet het gehele getal bevat, retourneert een HTTP 404-fout (niet gevonden). Retourneert bijvoorbeeld https://localhost:5001/Movies/Details een 404-fout. Als u de id optioneel wilt maken, voegt u deze toe aan ? de routebeperking:
@page "{id:int?}"
Test het gedrag van @page "{id:int?}":
- Stel de pagina-richtlijn in
Pages/Movies/Details.cshtmlop@page "{id:int?}". - Stel een onderbrekingspunt in
public async Task<IActionResult> OnGetAsync(int? id), inPages/Movies/Details.cshtml.cs. - Navigeer naar
https://localhost:5001/Movies/Details/.
Met de @page "{id:int}" richtlijn wordt het onderbrekingspunt nooit bereikt. De routeringsengine retourneert HTTP 404.
@page "{id:int?}" De OnGetAsyncmethode retourneert NotFound (HTTP 404):
public async Task<IActionResult> OnGetAsync(int? id)
{
if (id == null)
{
return NotFound();
}
var movie = await _context.Movie.FirstOrDefaultAsync(m => m.Id == id);
if (movie == null)
{
return NotFound();
}
else
{
Movie = movie;
}
return Page();
}
Afhandeling van gelijktijdigheidsonderzondering controleren
Controleer de OnPostAsync methode in het Pages/Movies/Edit.cshtml.cs bestand:
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
_context.Attach(Movie).State = EntityState.Modified;
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!MovieExists(Movie.Id))
{
return NotFound();
}
else
{
throw;
}
}
return RedirectToPage("./Index");
}
private bool MovieExists(int id)
{
return _context.Movie.Any(e => e.Id == id);
}
Met de vorige code worden gelijktijdigheidsonderingen gedetecteerd wanneer de ene client de film verwijdert en de andere client wijzigingen in de film plaatst.
Het catch-blok testen:
- Stel een onderbrekingspunt in op
catch (DbUpdateConcurrencyException). - Selecteer Bewerken voor een film, breng wijzigingen aan, maar voer Opslaan niet in.
- Selecteer in een ander browservenster de koppeling Verwijderen voor dezelfde film en verwijder de film.
- In het vorige browservenster plaatst u wijzigingen in de film.
Productiecode zou gelijktijdigheidsconflicten kunnen detecteren. Raadpleeg Gelijktijdigheidsconflicten afhandelen voor meer informatie.
Boekings- en bindingsbeoordeling
Bekijk het Pages/Movies/Edit.cshtml.cs bestand:
public class EditModel : PageModel
{
private readonly RazorPagesMovie.Data.RazorPagesMovieContext _context;
public EditModel(RazorPagesMovie.Data.RazorPagesMovieContext context)
{
_context = context;
}
[BindProperty]
public Movie Movie { get; set; } = default!;
public async Task<IActionResult> OnGetAsync(int? id)
{
if (id == null)
{
return NotFound();
}
var movie = await _context.Movie.FirstOrDefaultAsync(m => m.Id == id);
if (movie == null)
{
return NotFound();
}
Movie = movie;
return Page();
}
// To protect from overposting attacks, enable the specific properties you want to bind to.
// For more details, see https://aka.ms/RazorPagesCRUD.
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
_context.Attach(Movie).State = EntityState.Modified;
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!MovieExists(Movie.Id))
{
return NotFound();
}
else
{
throw;
}
}
return RedirectToPage("./Index");
}
private bool MovieExists(int id)
{
return _context.Movie.Any(e => e.Id == id);
}
Wanneer een HTTP GET-aanvraag wordt ingediend op de pagina Films/Bewerken, https://localhost:5001/Movies/Edit/3bijvoorbeeld:
- De
OnGetAsyncmethode haalt de film op uit de database en retourneert dePagemethode. - De
Pagemethode geeft dePages/Movies/Edit.cshtmlRazor pagina weer. HetPages/Movies/Edit.cshtmlbestand bevat de modelrichtlijn@model RazorPagesMovie.Pages.Movies.EditModel, waardoor het filmmodel beschikbaar is op de pagina. - Het formulier Bewerken wordt weergegeven met de waarden uit de film.
Wanneer de pagina Films/Bewerken wordt geplaatst:
De formulierwaarden op de pagina zijn gebonden aan de
Movieeigenschap. Het[BindProperty]kenmerk maakt modelbinding mogelijk.[BindProperty] public Movie Movie { get; set; }Als er fouten zijn in de modelstatus, bijvoorbeeld,
ReleaseDatekan niet worden omgezet in een datum, wordt het formulier opnieuw weergegeven met de ingediende waarden.Als er geen modelfouten zijn, wordt de film opgeslagen.
De HTTP GET-methoden in de pagina's Index, Maken en Verwijderen Razor volgen een vergelijkbaar patroon. De HTTP POST-methode OnPostAsync in de create Razor page volgt een vergelijkbaar patroon als de OnPostAsync methode in de bewerkingspagina Razor .
Volgende stappen
De opgebouwde filmapplicatie heeft een goed begin, maar de presentatie is niet ideaal. ReleaseDatum moet twee woorden zijn: Releasedatum.
Het model bijwerken
Werk Models/Movie.cs bij met de volgende gemarkeerde code:
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace RazorPagesMovie.Models;
public class Movie
{
public int Id { get; set; }
public string Title { get; set; } = string.Empty;
[Display(Name = "Release Date")]
[DataType(DataType.Date)]
public DateTime ReleaseDate { get; set; }
public string Genre { get; set; } = string.Empty;
[Column(TypeName = "decimal(18, 2)")]
public decimal Price { get; set; }
}
In de vorige code:
- Met de
[Column(TypeName = "decimal(18, 2)")]gegevensaantekening kan Entity Framework CorePricecorrect toewijzen aan valuta in de database. Zie gegevenstypenvoor meer informatie. - Het kenmerk [Weergave] geeft de weergavenaam van een veld op. In de voorgaande code,
Release Datein plaats vanReleaseDate. - Het kenmerk [DataType] geeft het type van de gegevens (
Date). De tijdgegevens die in het veld zijn opgeslagen, worden niet weergegeven.
DataAnnotations wordt behandeld in de volgende zelfstudie.
Blader naar Pagina's/Films en beweeg de muisaanwijzer over een koppeling Bewerken om de doel-URL te bekijken.
De koppelingen Bewerken, Details en Verwijderen worden gegenereerd door de Anchor Tag Helper in het Pages/Movies/Index.cshtml bestand.
@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>
Tag Helpers zorgen ervoor dat code aan de serverzijde kan deelnemen aan het maken en weergeven van HTML-elementen in Razor bestanden.
In de voorgaande code genereert de Anchor Tag Helper dynamisch de HTML-kenmerkwaarde href van de Razor pagina (de route is relatief), de asp-pageen de route-id (asp-route-id). Zie URL-generatie voor pagina's voor meer informatie.
Gebruik De weergavebron vanuit een browser om de gegenereerde markeringen te onderzoeken. Hieronder ziet u een deel van de gegenereerde HTML:
<td>
<a href="/Movies/Edit?id=1">Edit</a> |
<a href="/Movies/Details?id=1">Details</a> |
<a href="/Movies/Delete?id=1">Delete</a>
</td>
De dynamisch gegenereerde koppelingen geven de film-id door aan een queryreeks. Bijvoorbeeld de ?id=1 in https://localhost:5001/Movies/Details?id=1.
Routesjabloon toevoegen
Pas de pagina's Bewerken, Details en Verwijderen Razor aan om de {id:int} routesjabloon te gebruiken. Wijzig de pagina-instructie voor elk van deze pagina's van @page in @page "{id:int}". Voer de app uit en bekijk vervolgens de bron.
De gegenereerde HTML voegt de ID toe aan het padgedeelte van de URL.
<td>
<a href="/Movies/Edit/1">Edit</a> |
<a href="/Movies/Details/1">Details</a> |
<a href="/Movies/Delete/1">Delete</a>
</td>
Een aanvraag naar de pagina met de {id:int} routesjabloon die niet het gehele getal bevat, retourneert een HTTP 404-fout (niet gevonden). Retourneert bijvoorbeeld https://localhost:5001/Movies/Details een 404-fout. Als u de id optioneel wilt maken, voegt u deze toe aan ? de routebeperking:
@page "{id:int?}"
Test het gedrag van @page "{id:int?}":
- Stel de pagina-richtlijn in
Pages/Movies/Details.cshtmlop@page "{id:int?}". - Stel een onderbrekingspunt in
public async Task<IActionResult> OnGetAsync(int? id), inPages/Movies/Details.cshtml.cs. - Navigeer naar
https://localhost:5001/Movies/Details/.
Met de @page "{id:int}" richtlijn wordt het onderbrekingspunt nooit bereikt. De routeringsengine retourneert HTTP 404.
@page "{id:int?}" De OnGetAsyncmethode retourneert NotFound (HTTP 404):
public async Task<IActionResult> OnGetAsync(int? id)
{
if (id == null)
{
return NotFound();
}
Movie = await _context.Movie.FirstOrDefaultAsync(m => m.ID == id);
if (Movie == null)
{
return NotFound();
}
return Page();
}
Afhandeling van gelijktijdigheidsonderzondering controleren
Controleer de OnPostAsync methode in het Pages/Movies/Edit.cshtml.cs bestand:
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
_context.Attach(Movie).State = EntityState.Modified;
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!MovieExists(Movie.Id))
{
return NotFound();
}
else
{
throw;
}
}
return RedirectToPage("./Index");
}
private bool MovieExists(int id)
{
return _context.Movie.Any(e => e.Id == id);
}
Met de vorige code worden gelijktijdigheidsonderingen gedetecteerd wanneer de ene client de film verwijdert en de andere client wijzigingen in de film plaatst.
Het catch-blok testen:
- Stel een onderbrekingspunt in op
catch (DbUpdateConcurrencyException). - Selecteer Bewerken voor een film, breng wijzigingen aan, maar voer Opslaan niet in.
- Selecteer in een ander browservenster de koppeling Verwijderen voor dezelfde film en verwijder de film.
- In het vorige browservenster plaatst u wijzigingen in de film.
Productiecode zou gelijktijdigheidsconflicten kunnen detecteren. Raadpleeg Gelijktijdigheidsconflicten afhandelen voor meer informatie.
Boekings- en bindingsbeoordeling
Bekijk het Pages/Movies/Edit.cshtml.cs bestand:
public class EditModel : PageModel
{
private readonly RazorPagesMovie.Data.RazorPagesMovieContext _context;
public EditModel(RazorPagesMovie.Data.RazorPagesMovieContext context)
{
_context = context;
}
[BindProperty]
public Movie Movie { get; set; } = default!;
public async Task<IActionResult> OnGetAsync(int? id)
{
if (id == null || _context.Movie == null)
{
return NotFound();
}
var movie = await _context.Movie.FirstOrDefaultAsync(m => m.Id == id);
if (movie == null)
{
return NotFound();
}
Movie = movie;
return Page();
}
// To protect from overposting attacks, enable the specific properties you want to bind to.
// For more details, see https://aka.ms/RazorPagesCRUD.
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
_context.Attach(Movie).State = EntityState.Modified;
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!MovieExists(Movie.Id))
{
return NotFound();
}
else
{
throw;
}
}
return RedirectToPage("./Index");
}
private bool MovieExists(int id)
{
return _context.Movie.Any(e => e.Id == id);
}
Wanneer een HTTP GET-aanvraag wordt ingediend op de pagina Films/Bewerken, https://localhost:5001/Movies/Edit/3bijvoorbeeld:
- De
OnGetAsyncmethode haalt de film op uit de database en retourneert dePagemethode. - De
Pagemethode geeft dePages/Movies/Edit.cshtmlRazor pagina weer. HetPages/Movies/Edit.cshtmlbestand bevat de modelrichtlijn@model RazorPagesMovie.Pages.Movies.EditModel, waardoor het filmmodel beschikbaar is op de pagina. - Het formulier Bewerken wordt weergegeven met de waarden uit de film.
Wanneer de pagina Films/Bewerken wordt geplaatst:
De formulierwaarden op de pagina zijn gebonden aan de
Movieeigenschap. Het[BindProperty]kenmerk maakt modelbinding mogelijk.[BindProperty] public Movie Movie { get; set; }Als er fouten zijn in de modelstatus, bijvoorbeeld,
ReleaseDatekan niet worden omgezet in een datum, wordt het formulier opnieuw weergegeven met de ingediende waarden.Als er geen modelfouten zijn, wordt de film opgeslagen.
De HTTP GET-methoden in de pagina's Index, Maken en Verwijderen Razor volgen een vergelijkbaar patroon. De HTTP POST-methode OnPostAsync in de create Razor page volgt een vergelijkbaar patroon als de OnPostAsync methode in de bewerkingspagina Razor .
Volgende stappen
De opgebouwde filmapplicatie heeft een goed begin, maar de presentatie is niet ideaal. ReleaseDatum moet twee woorden zijn: Releasedatum.
Het model bijwerken
Werk Models/Movie.cs bij met de volgende gemarkeerde code:
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace RazorPagesMovie.Models;
public class Movie
{
public int Id { get; set; }
public string Title { get; set; } = string.Empty;
[Display(Name = "Release Date")]
[DataType(DataType.Date)]
public DateTime ReleaseDate { get; set; }
public string Genre { get; set; } = string.Empty;
[Column(TypeName = "decimal(18, 2)")]
public decimal Price { get; set; }
}
In de vorige code:
- Met de
[Column(TypeName = "decimal(18, 2)")]gegevensaantekening kan Entity Framework CorePricecorrect toewijzen aan valuta in de database. Zie gegevenstypenvoor meer informatie. - Het kenmerk [Weergave] geeft de weergavenaam van een veld op. In de voorgaande code,
Release Datein plaats vanReleaseDate. - Het kenmerk [DataType] geeft het type van de gegevens (
Date). De tijdgegevens die in het veld zijn opgeslagen, worden niet weergegeven.
DataAnnotations wordt behandeld in de volgende zelfstudie.
Blader naar Pagina's/Films en beweeg de muisaanwijzer over een koppeling Bewerken om de doel-URL te bekijken.
De koppelingen Bewerken, Details en Verwijderen worden gegenereerd door de Anchor Tag Helper in het Pages/Movies/Index.cshtml bestand.
@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>
Tag Helpers zorgen ervoor dat code aan de serverzijde kan deelnemen aan het maken en weergeven van HTML-elementen in Razor bestanden.
In de voorgaande code genereert de Anchor Tag Helper dynamisch de HTML-kenmerkwaarde href van de Razor pagina (de route is relatief), de asp-pageen de route-id (asp-route-id). Zie URL-generatie voor pagina's voor meer informatie.
Gebruik De weergavebron vanuit een browser om de gegenereerde markeringen te onderzoeken. Hieronder ziet u een deel van de gegenereerde HTML:
<td>
<a href="/Movies/Edit?id=1">Edit</a> |
<a href="/Movies/Details?id=1">Details</a> |
<a href="/Movies/Delete?id=1">Delete</a>
</td>
De dynamisch gegenereerde koppelingen geven de film-id door aan een queryreeks. Bijvoorbeeld de ?id=1 in https://localhost:5001/Movies/Details?id=1.
Routesjabloon toevoegen
Pas de pagina's Bewerken, Details en Verwijderen Razor aan om de {id:int} routesjabloon te gebruiken. Wijzig de pagina-instructie voor elk van deze pagina's van @page in @page "{id:int}". Voer de app uit en bekijk vervolgens de bron.
De gegenereerde HTML voegt de ID toe aan het padgedeelte van de URL.
<td>
<a href="/Movies/Edit/1">Edit</a> |
<a href="/Movies/Details/1">Details</a> |
<a href="/Movies/Delete/1">Delete</a>
</td>
Een aanvraag naar de pagina met de {id:int} routesjabloon die niet het gehele getal bevat, retourneert een HTTP 404-fout (niet gevonden). Retourneert bijvoorbeeld https://localhost:5001/Movies/Details een 404-fout. Als u de id optioneel wilt maken, voegt u deze toe aan ? de routebeperking:
@page "{id:int?}"
Test het gedrag van @page "{id:int?}":
- Stel de pagina-richtlijn in
Pages/Movies/Details.cshtmlop@page "{id:int?}". - Stel een onderbrekingspunt in
public async Task<IActionResult> OnGetAsync(int? id), inPages/Movies/Details.cshtml.cs. - Navigeer naar
https://localhost:5001/Movies/Details/.
Met de @page "{id:int}" richtlijn wordt het onderbrekingspunt nooit bereikt. De routeringsengine retourneert HTTP 404.
@page "{id:int?}" De OnGetAsyncmethode retourneert NotFound (HTTP 404):
public async Task<IActionResult> OnGetAsync(int? id)
{
if (id == null)
{
return NotFound();
}
Movie = await _context.Movie.FirstOrDefaultAsync(m => m.ID == id);
if (Movie == null)
{
return NotFound();
}
return Page();
}
Afhandeling van gelijktijdigheidsonderzondering controleren
Controleer de OnPostAsync methode in het Pages/Movies/Edit.cshtml.cs bestand:
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
_context.Attach(Movie).State = EntityState.Modified;
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!MovieExists(Movie.Id))
{
return NotFound();
}
else
{
throw;
}
}
return RedirectToPage("./Index");
}
private bool MovieExists(int id)
{
return _context.Movie.Any(e => e.Id == id);
}
Met de vorige code worden gelijktijdigheidsonderingen gedetecteerd wanneer de ene client de film verwijdert en de andere client wijzigingen in de film plaatst.
Het catch-blok testen:
- Stel een onderbrekingspunt in op
catch (DbUpdateConcurrencyException). - Selecteer Bewerken voor een film, breng wijzigingen aan, maar voer Opslaan niet in.
- Selecteer in een ander browservenster de koppeling Verwijderen voor dezelfde film en verwijder de film.
- In het vorige browservenster plaatst u wijzigingen in de film.
Productiecode zou gelijktijdigheidsconflicten kunnen detecteren. Raadpleeg Gelijktijdigheidsconflicten afhandelen voor meer informatie.
Boekings- en bindingsbeoordeling
Bekijk het Pages/Movies/Edit.cshtml.cs bestand:
public class EditModel : PageModel
{
private readonly RazorPagesMovie.Data.RazorPagesMovieContext _context;
public EditModel(RazorPagesMovie.Data.RazorPagesMovieContext context)
{
_context = context;
}
[BindProperty]
public Movie Movie { get; set; } = default!;
public async Task<IActionResult> OnGetAsync(int? id)
{
if (id == null || _context.Movie == null)
{
return NotFound();
}
var movie = await _context.Movie.FirstOrDefaultAsync(m => m.Id == id);
if (movie == null)
{
return NotFound();
}
Movie = movie;
return Page();
}
// To protect from overposting attacks, enable the specific properties you want to bind to.
// For more details, see https://aka.ms/RazorPagesCRUD.
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
_context.Attach(Movie).State = EntityState.Modified;
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!MovieExists(Movie.Id))
{
return NotFound();
}
else
{
throw;
}
}
return RedirectToPage("./Index");
}
private bool MovieExists(int id)
{
return _context.Movie.Any(e => e.Id == id);
}
Wanneer een HTTP GET-aanvraag wordt ingediend op de pagina Films/Bewerken, https://localhost:5001/Movies/Edit/3bijvoorbeeld:
- De
OnGetAsyncmethode haalt de film op uit de database en retourneert dePagemethode. - De
Pagemethode geeft dePages/Movies/Edit.cshtmlRazor pagina weer. HetPages/Movies/Edit.cshtmlbestand bevat de modelrichtlijn@model RazorPagesMovie.Pages.Movies.EditModel, waardoor het filmmodel beschikbaar is op de pagina. - Het formulier Bewerken wordt weergegeven met de waarden uit de film.
Wanneer de pagina Films/Bewerken wordt geplaatst:
De formulierwaarden op de pagina zijn gebonden aan de
Movieeigenschap. Het[BindProperty]kenmerk maakt modelbinding mogelijk.[BindProperty] public Movie Movie { get; set; }Als er fouten zijn in de modelstatus, bijvoorbeeld,
ReleaseDatekan niet worden omgezet in een datum, wordt het formulier opnieuw weergegeven met de ingediende waarden.Als er geen modelfouten zijn, wordt de film opgeslagen.
De HTTP GET-methoden in de pagina's Index, Maken en Verwijderen Razor volgen een vergelijkbaar patroon. De HTTP POST-methode OnPostAsync in de create Razor page volgt een vergelijkbaar patroon als de OnPostAsync methode in de bewerkingspagina Razor .
Volgende stappen
De opgebouwde filmapplicatie heeft een goed begin, maar de presentatie is niet ideaal. ReleaseDatum moet twee woorden zijn: Releasedatum.
De gegenereerde code bijwerken
Werk Models/Movie.cs bij met de volgende gemarkeerde code:
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace RazorPagesMovie.Models
{
public class Movie
{
public int ID { get; set; }
public string Title { get; set; } = string.Empty;
[Display(Name = "Release Date")]
[DataType(DataType.Date)]
public DateTime ReleaseDate { get; set; }
public string Genre { get; set; } = string.Empty;
[Column(TypeName = "decimal(18, 2)")]
public decimal Price { get; set; }
}
}
In de vorige code:
- Met de
[Column(TypeName = "decimal(18, 2)")]gegevensaantekening kan Entity Framework CorePricecorrect toewijzen aan valuta in de database. Zie gegevenstypenvoor meer informatie. - Het kenmerk [Weergave] geeft de weergavenaam van een veld op. In de voorgaande code, 'ReleaseDatum' in plaats van 'ReleaseDate'.
- Het kenmerk [DataType] geeft het type van de gegevens (
Date). De tijdgegevens die in het veld zijn opgeslagen, worden niet weergegeven.
DataAnnotations wordt behandeld in de volgende zelfstudie.
Blader naar Pagina's/Films en beweeg de muisaanwijzer over een koppeling Bewerken om de doel-URL te bekijken.
De koppelingen Bewerken, Details en Verwijderen worden gegenereerd door de Anchor Tag Helper in het Pages/Movies/Index.cshtml bestand.
@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>
Tag Helpers zorgen ervoor dat code aan de serverzijde kan deelnemen aan het maken en weergeven van HTML-elementen in Razor bestanden.
In de voorgaande code genereert de Anchor Tag Helper dynamisch de HTML-kenmerkwaarde href van de Razor pagina (de route is relatief), de asp-pageen de route-id (asp-route-id). Zie URL-generatie voor pagina's voor meer informatie.
Gebruik De weergavebron vanuit een browser om de gegenereerde markeringen te onderzoeken. Hieronder ziet u een deel van de gegenereerde HTML:
<td>
<a href="/Movies/Edit?id=1">Edit</a> |
<a href="/Movies/Details?id=1">Details</a> |
<a href="/Movies/Delete?id=1">Delete</a>
</td>
De dynamisch gegenereerde koppelingen geven de film-id door aan een queryreeks. Bijvoorbeeld de ?id=1 in https://localhost:5001/Movies/Details?id=1.
Routesjabloon toevoegen
Pas de pagina's Bewerken, Details en Verwijderen Razor aan om de {id:int} routesjabloon te gebruiken. Wijzig de pagina-instructie voor elk van deze pagina's van @page in @page "{id:int}". Voer de app uit en bekijk vervolgens de bron.
De gegenereerde HTML voegt de ID toe aan het padgedeelte van de URL.
<td>
<a href="/Movies/Edit/1">Edit</a> |
<a href="/Movies/Details/1">Details</a> |
<a href="/Movies/Delete/1">Delete</a>
</td>
Een aanvraag naar de pagina met de {id:int} routesjabloon die niet het gehele getal bevat, retourneert een HTTP 404-fout (niet gevonden). Retourneert bijvoorbeeld https://localhost:5001/Movies/Details een 404-fout. Als u de id optioneel wilt maken, voegt u deze toe aan ? de routebeperking:
@page "{id:int?}"
Test het gedrag van @page "{id:int?}":
- Stel de pagina-richtlijn in
Pages/Movies/Details.cshtmlop@page "{id:int?}". - Stel een onderbrekingspunt in
public async Task<IActionResult> OnGetAsync(int? id), inPages/Movies/Details.cshtml.cs. - Navigeer naar
https://localhost:5001/Movies/Details/.
Met de @page "{id:int}" richtlijn wordt het onderbrekingspunt nooit bereikt. De routeringsengine retourneert HTTP 404.
@page "{id:int?}" De OnGetAsyncmethode retourneert NotFound (HTTP 404):
public async Task<IActionResult> OnGetAsync(int? id)
{
if (id == null)
{
return NotFound();
}
Movie = await _context.Movie.FirstOrDefaultAsync(m => m.ID == id);
if (Movie == null)
{
return NotFound();
}
return Page();
}
Afhandeling van gelijktijdigheidsonderzondering controleren
Controleer de OnPostAsync methode in het Pages/Movies/Edit.cshtml.cs bestand:
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
_context.Attach(Movie).State = EntityState.Modified;
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!MovieExists(Movie.ID))
{
return NotFound();
}
else
{
throw;
}
}
return RedirectToPage("./Index");
}
private bool MovieExists(int id)
{
return (_context.Movie?.Any(e => e.ID == id)).GetValueOrDefault();
}
Met de vorige code worden gelijktijdigheidsonderingen gedetecteerd wanneer de ene client de film verwijdert en de andere client wijzigingen in de film plaatst. De vorige code detecteert geen conflicten die optreden vanwege twee of meer clients die dezelfde film gelijktijdig bewerken. In dit geval worden bewerkingen door meerdere clients toegepast in de volgorde waarin SaveChanges wordt aangeroepen, en bewerkingen die later worden toegepast, kunnen eerdere bewerkingen met verouderde waarden overschrijven.
Het catch-blok testen:
- Stel een onderbrekingspunt in op
catch (DbUpdateConcurrencyException). - Selecteer Bewerken voor een film, breng wijzigingen aan, maar voer Opslaan niet in.
- Selecteer in een ander browservenster de koppeling Verwijderen voor dezelfde film en verwijder de film.
- In het vorige browservenster plaatst u wijzigingen in de film.
Productiecode kan extra gelijktijdigheidsconflicten detecteren, zoals meerdere clients die tegelijkertijd een entiteit bewerken. Raadpleeg Gelijktijdigheidsconflicten afhandelen voor meer informatie.
Boekings- en bindingsbeoordeling
Bekijk het Pages/Movies/Edit.cshtml.cs bestand:
public class EditModel : PageModel
{
private readonly RazorPagesMovie.Data.RazorPagesMovieContext _context;
public EditModel(RazorPagesMovie.Data.RazorPagesMovieContext context)
{
_context = context;
}
[BindProperty]
public Movie Movie { get; set; } = default!;
public async Task<IActionResult> OnGetAsync(int? id)
{
if (id == null || _context.Movie == null)
{
return NotFound();
}
var movie = await _context.Movie.FirstOrDefaultAsync(m => m.ID == id);
if (movie == null)
{
return NotFound();
}
Movie = movie;
return Page();
}
// To protect from overposting attacks, enable the specific properties you want to bind to.
// For more details, see https://aka.ms/RazorPagesCRUD.
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
_context.Attach(Movie).State = EntityState.Modified;
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!MovieExists(Movie.ID))
{
return NotFound();
}
else
{
throw;
}
}
return RedirectToPage("./Index");
}
private bool MovieExists(int id)
{
return (_context.Movie?.Any(e => e.ID == id)).GetValueOrDefault();
}
Wanneer een HTTP GET-aanvraag wordt ingediend op de pagina Films/Bewerken, https://localhost:5001/Movies/Edit/3bijvoorbeeld:
- De
OnGetAsyncmethode haalt de film op uit de database en retourneert dePagemethode. - De
Pagemethode geeft dePages/Movies/Edit.cshtmlRazor pagina weer. HetPages/Movies/Edit.cshtmlbestand bevat de modelrichtlijn@model RazorPagesMovie.Pages.Movies.EditModel, waardoor het filmmodel beschikbaar is op de pagina. - Het formulier Bewerken wordt weergegeven met de waarden uit de film.
Wanneer de pagina Films/Bewerken wordt geplaatst:
De formulierwaarden op de pagina zijn gebonden aan de
Movieeigenschap. Het[BindProperty]kenmerk maakt modelbinding mogelijk.[BindProperty] public Movie Movie { get; set; }Als er fouten zijn in de modelstatus, bijvoorbeeld,
ReleaseDatekan niet worden omgezet in een datum, wordt het formulier opnieuw weergegeven met de ingediende waarden.Als er geen modelfouten zijn, wordt de film opgeslagen.
De HTTP GET-methoden in de pagina's Index, Maken en Verwijderen Razor volgen een vergelijkbaar patroon. De HTTP POST-methode OnPostAsync in de create Razor page volgt een vergelijkbaar patroon als de OnPostAsync methode in de bewerkingspagina Razor .
Volgende stappen
De opgebouwde filmapplicatie heeft een goed begin, maar de presentatie is niet ideaal. ReleaseDatum moet twee woorden zijn: Releasedatum.
De gegenereerde code bijwerken
Open het Models/Movie.cs bestand en voeg de gemarkeerde regels toe die worden weergegeven in de volgende code:
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace RazorPagesMovie.Models
{
public class Movie
{
public int ID { get; set; }
public string Title { get; set; }
[Display(Name = "Release Date")]
[DataType(DataType.Date)]
public DateTime ReleaseDate { get; set; }
public string Genre { get; set; }
[Column(TypeName = "decimal(18, 2)")]
public decimal Price { get; set; }
}
}
In de vorige code:
- Met de
[Column(TypeName = "decimal(18, 2)")]gegevensaantekening kan Entity Framework CorePricecorrect toewijzen aan valuta in de database. Zie gegevenstypenvoor meer informatie. - Het kenmerk [Weergave] geeft de weergavenaam van een veld op. In de voorgaande code, 'ReleaseDatum' in plaats van 'ReleaseDate'.
- Het kenmerk [DataType] geeft het type van de gegevens (
Date). De tijdgegevens die in het veld zijn opgeslagen, worden niet weergegeven.
DataAnnotations wordt behandeld in de volgende zelfstudie.
Blader naar Pagina's/Films en beweeg de muisaanwijzer over een koppeling Bewerken om de doel-URL te bekijken.
De koppelingen Bewerken, Details en Verwijderen worden gegenereerd door de Anchor Tag Helper in het Pages/Movies/Index.cshtml bestand.
@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>
Tag Helpers zorgen ervoor dat code aan de serverzijde kan deelnemen aan het maken en weergeven van HTML-elementen in Razor bestanden.
In de voorgaande code genereert de Anchor Tag Helper dynamisch de HTML-kenmerkwaarde href van de Razor pagina (de route is relatief), de asp-pageen de route-id (asp-route-id). Zie URL-generatie voor pagina's voor meer informatie.
Gebruik De weergavebron vanuit een browser om de gegenereerde markeringen te onderzoeken. Hieronder ziet u een deel van de gegenereerde HTML:
<td>
<a href="/Movies/Edit?id=1">Edit</a> |
<a href="/Movies/Details?id=1">Details</a> |
<a href="/Movies/Delete?id=1">Delete</a>
</td>
De dynamisch gegenereerde koppelingen geven de film-id door aan een queryreeks. Bijvoorbeeld de ?id=1 in https://localhost:5001/Movies/Details?id=1.
Routesjabloon toevoegen
Pas de pagina's Bewerken, Details en Verwijderen Razor aan om de {id:int} routesjabloon te gebruiken. Wijzig de pagina-instructie voor elk van deze pagina's van @page in @page "{id:int}". Voer de app uit en bekijk vervolgens de bron.
De gegenereerde HTML voegt de ID toe aan het padgedeelte van de URL.
<td>
<a href="/Movies/Edit/1">Edit</a> |
<a href="/Movies/Details/1">Details</a> |
<a href="/Movies/Delete/1">Delete</a>
</td>
Een aanvraag naar de pagina met de {id:int} routesjabloon die niet het gehele getal bevat, retourneert een HTTP 404-fout (niet gevonden). Retourneert bijvoorbeeld https://localhost:5001/Movies/Details een 404-fout. Als u de id optioneel wilt maken, voegt u deze toe aan ? de routebeperking:
@page "{id:int?}"
Test het gedrag van @page "{id:int?}":
- Stel de pagina-richtlijn in
Pages/Movies/Details.cshtmlop@page "{id:int?}". - Stel een onderbrekingspunt in
public async Task<IActionResult> OnGetAsync(int? id), inPages/Movies/Details.cshtml.cs. - Navigeer naar
https://localhost:5001/Movies/Details/.
Met de @page "{id:int}" richtlijn wordt het onderbrekingspunt nooit bereikt. De routeringsengine retourneert HTTP 404.
@page "{id:int?}" De OnGetAsyncmethode retourneert NotFound (HTTP 404):
public async Task<IActionResult> OnGetAsync(int? id)
{
if (id == null)
{
return NotFound();
}
Movie = await _context.Movie.FirstOrDefaultAsync(m => m.ID == id);
if (Movie == null)
{
return NotFound();
}
return Page();
}
Afhandeling van gelijktijdigheidsonderzondering controleren
Controleer de OnPostAsync methode in het Pages/Movies/Edit.cshtml.cs bestand:
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
_context.Attach(Movie).State = EntityState.Modified;
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!MovieExists(Movie.ID))
{
return NotFound();
}
else
{
throw;
}
}
return RedirectToPage("./Index");
}
private bool MovieExists(int id)
{
return _context.Movie.Any(e => e.ID == id);
}
Met de vorige code worden gelijktijdigheidsonderingen gedetecteerd wanneer de ene client de film verwijdert en de andere client wijzigingen in de film plaatst.
Het catch-blok testen:
- Stel een onderbrekingspunt in op
catch (DbUpdateConcurrencyException). - Selecteer Bewerken voor een film, breng wijzigingen aan, maar voer Opslaan niet in.
- Selecteer in een ander browservenster de koppeling Verwijderen voor dezelfde film en verwijder de film.
- In het vorige browservenster plaatst u wijzigingen in de film.
Productiecode zou gelijktijdigheidsconflicten kunnen detecteren. Raadpleeg Gelijktijdigheidsconflicten afhandelen voor meer informatie.
Boekings- en bindingsbeoordeling
Bekijk het Pages/Movies/Edit.cshtml.cs bestand:
public class EditModel : PageModel
{
private readonly RazorPagesMovie.Data.RazorPagesMovieContext _context;
public EditModel(RazorPagesMovie.Data.RazorPagesMovieContext context)
{
_context = context;
}
[BindProperty]
public Movie Movie { get; set; }
public async Task<IActionResult> OnGetAsync(int? id)
{
if (id == null)
{
return NotFound();
}
Movie = await _context.Movie.FirstOrDefaultAsync(m => m.ID == id);
if (Movie == null)
{
return NotFound();
}
return Page();
}
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
_context.Attach(Movie).State = EntityState.Modified;
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!MovieExists(Movie.ID))
{
return NotFound();
}
else
{
throw;
}
}
return RedirectToPage("./Index");
}
private bool MovieExists(int id)
{
return _context.Movie.Any(e => e.ID == id);
}
Wanneer een HTTP GET-aanvraag wordt ingediend op de pagina Films/Bewerken, https://localhost:5001/Movies/Edit/3bijvoorbeeld:
- De
OnGetAsyncmethode haalt de film op uit de database en retourneert dePagemethode. - De
Pagemethode geeft dePages/Movies/Edit.cshtmlRazor pagina weer. HetPages/Movies/Edit.cshtmlbestand bevat de modelrichtlijn@model RazorPagesMovie.Pages.Movies.EditModel, waardoor het filmmodel beschikbaar is op de pagina. - Het formulier Bewerken wordt weergegeven met de waarden uit de film.
Wanneer de pagina Films/Bewerken wordt geplaatst:
De formulierwaarden op de pagina zijn gebonden aan de
Movieeigenschap. Het[BindProperty]kenmerk maakt modelbinding mogelijk.[BindProperty] public Movie Movie { get; set; }Als er fouten zijn in de modelstatus, bijvoorbeeld,
ReleaseDatekan niet worden omgezet in een datum, wordt het formulier opnieuw weergegeven met de ingediende waarden.Als er geen modelfouten zijn, wordt de film opgeslagen.
De HTTP GET-methoden in de pagina's Index, Maken en Verwijderen Razor volgen een vergelijkbaar patroon. De HTTP POST-methode OnPostAsync in de create Razor page volgt een vergelijkbaar patroon als de OnPostAsync methode in de bewerkingspagina Razor .