Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Poznámka:
Toto není nejnovější verze tohoto článku. Aktuální verzi najdete ve verzi .NET 10 tohoto článku.
Upozorňující
Tato verze ASP.NET Core se už nepodporuje. Další informace najdete v zásadách podpory .NET a .NET Core. Aktuální verzi najdete v tomto článku ve verzi .NET 9.
Vygenerovaná filmová aplikace má dobrý začátek, ale prezentace není ideální. Datum vydání by mělo být dvě slova– Datum vydání.
Aktualizace modelu
Aktualizujte Models/Movie.cs následujícím zvýrazněným kódem:
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; }
}
V předchozím kódu:
- Datová
[Column(TypeName = "decimal(18, 2)")]poznámka umožňuje entity Framework Core správně mapovatPricena měnu v databázi. Další informace naleznete v tématu Datové typy. - Atribut [Display] určuje zobrazovaný název pole. V předchozím kódu místo
Release DateReleaseDate. - Atribut [DataType] určuje typ dat (
Date). Informace o čase uložené v poli se nezobrazují.
DataAnnotations najdete v dalším kurzu.
Přejděte na Stránky nebo filmy a najeďte myší na odkaz Upravit a zobrazte cílovou adresu URL.
Odkazy Upravit, Podrobnosti a Odstranit jsou generovány pomocným pomocníkem značky ukotvení v Pages/Movies/Index.cshtml souboru.
@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>
Pomocné rutiny značek umožňují, aby se kód na straně serveru v souborech Razor podílel na vytváření a vykreslování elementů HTML.
V předchozím kódu pomocník značky ukotvení dynamicky generuje hodnotu atributu HTML href ze Razor stránky (trasa je relativní), identifikátor asp-pagetrasyasp-route-id (). Další informace najdete v tématu Generování adres URL pro stránky.
K prozkoumání vygenerované značky použijte zdroj zobrazení z prohlížeče. Část vygenerovaného kódu HTML je znázorněná níže:
<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>
Dynamicky generované odkazy předávají ID videa s řetězcem dotazu. Například in ?id=1https://localhost:5001/Movies/Details?id=1.
Přidání šablony trasy
Aktualizujte stránky Upravit, Podrobnosti a Odstranit Razor tak, aby používaly {id:int} šablonu trasy. Změňte direktivu stránky pro každou z těchto stránek na @page@page "{id:int}". Spusťte aplikaci a pak zobrazte zdroj.
Vygenerovaný kód HTML přidá ID do části cesty adresy URL:
<td>
<a href="/Movies/Edit/1">Edit</a> |
<a href="/Movies/Details/1">Details</a> |
<a href="/Movies/Delete/1">Delete</a>
</td>
Požadavek na stránku se šablonou {id:int} trasy, která neobsahuje celé číslo, vrátí chybu HTTP 404 (nenalezena). Například https://localhost:5001/Movies/Details vrátí chybu 404. Pokud chcete nastavit ID jako volitelné, připojte k omezení trasy symbol ?:
@page "{id:int?}"
Otestujte chování @page "{id:int?}":
- Nastavte direktivu
Pages/Movies/Details.cshtmlstránky na@page "{id:int?}"hodnotu . - Nastavte zarážku v
public async Task<IActionResult> OnGetAsync(int? id), vPages/Movies/Details.cshtml.cs. - Přejděte na
https://localhost:5001/Movies/Details/.
S direktivou @page "{id:int}" se zarážka nikdy nedostane. Směrovací modul vrátí http 404. Using @page "{id:int?}", OnGetAsync metoda vrátí 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();
}
Kontrola zpracování výjimek souběžnosti
Zkontrolujte metodu OnPostAsyncPages/Movies/Edit.cshtml.cs v souboru:
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);
}
Předchozí kód zjistí výjimky souběžnosti, když jeden klient odstraní video a ostatní klienty publikují změny videa.
Postup otestování catch bloku:
- Nastavte zarážku na
catch (DbUpdateConcurrencyException). - Vyberte Upravit pro film, proveďte změny, ale nezadávejte uložit.
- V jiném okně prohlížeče vyberte odkaz Odstranit pro stejný film a pak video odstraňte.
- V předchozím okně prohlížeče publikujte změny videa.
Produkční kód může chtít zjistit konflikty souběžnosti. Další informace najdete v tématu Zpracování konfliktů souběžnosti.
Publikování a kontrola vazby
Pages/Movies/Edit.cshtml.cs Prozkoumejte soubor:
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);
}
Při provedení požadavku HTTP GET na stránku Filmy/Úpravy, například https://localhost:5001/Movies/Edit/3:
- Metoda
OnGetAsyncnačte film z databáze a vrátí metoduPage. - Metoda
PagevykreslíPages/Movies/Edit.cshtmlRazor Stránku. SouborPages/Movies/Edit.cshtmlobsahuje direktivu@model RazorPagesMovie.Pages.Movies.EditModelmodelu, která zpřístupňuje filmový model na stránce. - Formulář Upravit se zobrazí s hodnotami z filmu.
Když se publikuje stránka Movies/Edit:
Hodnoty formuláře na stránce jsou vázány na
Movievlastnost. Atribut[BindProperty]umožňuje vazbu modelu.[BindProperty] public Movie Movie { get; set; }Pokud jsou ve stavu modelu chyby,
ReleaseDatenapříklad nelze převést na datum, formulář se znovu zobrazí s odeslanými hodnotami.Pokud neexistují žádné chyby modelu, film se uloží.
Metody HTTP GET na stránkách Index, Create a Delete Razor se řídí podobným vzorem. Metoda HTTP POST OnPostAsync na create Razor page se řídí podobným vzorem OnPostAsync jako metoda v Edit Razor Page.
Další kroky
Vygenerovaná filmová aplikace má dobrý začátek, ale prezentace není ideální. Datum vydání by mělo být dvě slova– Datum vydání.
Aktualizace modelu
Aktualizujte Models/Movie.cs následujícím zvýrazněným kódem:
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; }
}
V předchozím kódu:
- Datová
[Column(TypeName = "decimal(18, 2)")]poznámka umožňuje entity Framework Core správně mapovatPricena měnu v databázi. Další informace naleznete v tématu Datové typy. - Atribut [Display] určuje zobrazovaný název pole. V předchozím kódu místo
Release DateReleaseDate. - Atribut [DataType] určuje typ dat (
Date). Informace o čase uložené v poli se nezobrazují.
DataAnnotations najdete v dalším kurzu.
Přejděte na Stránky nebo filmy a najeďte myší na odkaz Upravit a zobrazte cílovou adresu URL.
Odkazy Upravit, Podrobnosti a Odstranit jsou generovány pomocným pomocníkem značky ukotvení v Pages/Movies/Index.cshtml souboru.
@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>
Pomocné rutiny značek umožňují, aby se kód na straně serveru v souborech Razor podílel na vytváření a vykreslování elementů HTML.
V předchozím kódu pomocník značky ukotvení dynamicky generuje hodnotu atributu HTML href ze Razor stránky (trasa je relativní), identifikátor asp-pagetrasyasp-route-id (). Další informace najdete v tématu Generování adres URL pro stránky.
K prozkoumání vygenerované značky použijte zdroj zobrazení z prohlížeče. Část vygenerovaného kódu HTML je znázorněná níže:
<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>
Dynamicky generované odkazy předávají ID videa s řetězcem dotazu. Například in ?id=1https://localhost:5001/Movies/Details?id=1.
Přidání šablony trasy
Aktualizujte stránky Upravit, Podrobnosti a Odstranit Razor tak, aby používaly {id:int} šablonu trasy. Změňte direktivu stránky pro každou z těchto stránek na @page@page "{id:int}". Spusťte aplikaci a pak zobrazte zdroj.
Vygenerovaný kód HTML přidá ID do části cesty adresy URL:
<td>
<a href="/Movies/Edit/1">Edit</a> |
<a href="/Movies/Details/1">Details</a> |
<a href="/Movies/Delete/1">Delete</a>
</td>
Požadavek na stránku se šablonou {id:int} trasy, která neobsahuje celé číslo, vrátí chybu HTTP 404 (nenalezena). Například https://localhost:5001/Movies/Details vrátí chybu 404. Pokud chcete nastavit ID jako volitelné, připojte k omezení trasy symbol ?:
@page "{id:int?}"
Otestujte chování @page "{id:int?}":
- Nastavte direktivu
Pages/Movies/Details.cshtmlstránky na@page "{id:int?}"hodnotu . - Nastavte zarážku v
public async Task<IActionResult> OnGetAsync(int? id), vPages/Movies/Details.cshtml.cs. - Přejděte na
https://localhost:5001/Movies/Details/.
S direktivou @page "{id:int}" se zarážka nikdy nedostane. Směrovací modul vrátí http 404. Using @page "{id:int?}", OnGetAsync metoda vrátí 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();
}
Kontrola zpracování výjimek souběžnosti
Zkontrolujte metodu OnPostAsyncPages/Movies/Edit.cshtml.cs v souboru:
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);
}
Předchozí kód zjistí výjimky souběžnosti, když jeden klient odstraní video a ostatní klienty publikují změny videa.
Postup otestování catch bloku:
- Nastavte zarážku na
catch (DbUpdateConcurrencyException). - Vyberte Upravit pro film, proveďte změny, ale nezadávejte uložit.
- V jiném okně prohlížeče vyberte odkaz Odstranit pro stejný film a pak video odstraňte.
- V předchozím okně prohlížeče publikujte změny videa.
Produkční kód může chtít zjistit konflikty souběžnosti. Další informace najdete v tématu Zpracování konfliktů souběžnosti.
Publikování a kontrola vazby
Pages/Movies/Edit.cshtml.cs Prozkoumejte soubor:
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);
}
Při provedení požadavku HTTP GET na stránku Filmy/Úpravy, například https://localhost:5001/Movies/Edit/3:
- Metoda
OnGetAsyncnačte film z databáze a vrátí metoduPage. - Metoda
PagevykreslíPages/Movies/Edit.cshtmlRazor Stránku. SouborPages/Movies/Edit.cshtmlobsahuje direktivu@model RazorPagesMovie.Pages.Movies.EditModelmodelu, která zpřístupňuje filmový model na stránce. - Formulář Upravit se zobrazí s hodnotami z filmu.
Když se publikuje stránka Movies/Edit:
Hodnoty formuláře na stránce jsou vázány na
Movievlastnost. Atribut[BindProperty]umožňuje vazbu modelu.[BindProperty] public Movie Movie { get; set; }Pokud jsou ve stavu modelu chyby,
ReleaseDatenapříklad nelze převést na datum, formulář se znovu zobrazí s odeslanými hodnotami.Pokud neexistují žádné chyby modelu, film se uloží.
Metody HTTP GET na stránkách Index, Create a Delete Razor se řídí podobným vzorem. Metoda HTTP POST OnPostAsync na create Razor page se řídí podobným vzorem OnPostAsync jako metoda v Edit Razor Page.
Další kroky
Vygenerovaná filmová aplikace má dobrý začátek, ale prezentace není ideální. Datum vydání by mělo být dvě slova– Datum vydání.
Aktualizace modelu
Aktualizujte Models/Movie.cs následujícím zvýrazněným kódem:
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; }
}
V předchozím kódu:
- Datová
[Column(TypeName = "decimal(18, 2)")]poznámka umožňuje entity Framework Core správně mapovatPricena měnu v databázi. Další informace naleznete v tématu Datové typy. - Atribut [Display] určuje zobrazovaný název pole. V předchozím kódu místo
Release DateReleaseDate. - Atribut [DataType] určuje typ dat (
Date). Informace o čase uložené v poli se nezobrazují.
DataAnnotations najdete v dalším kurzu.
Přejděte na Stránky nebo filmy a najeďte myší na odkaz Upravit a zobrazte cílovou adresu URL.
Odkazy Upravit, Podrobnosti a Odstranit jsou generovány pomocným pomocníkem značky ukotvení v Pages/Movies/Index.cshtml souboru.
@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>
Pomocné rutiny značek umožňují, aby se kód na straně serveru v souborech Razor podílel na vytváření a vykreslování elementů HTML.
V předchozím kódu pomocník značky ukotvení dynamicky generuje hodnotu atributu HTML href ze Razor stránky (trasa je relativní), identifikátor asp-pagetrasyasp-route-id (). Další informace najdete v tématu Generování adres URL pro stránky.
K prozkoumání vygenerované značky použijte zdroj zobrazení z prohlížeče. Část vygenerovaného kódu HTML je znázorněná níže:
<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>
Dynamicky generované odkazy předávají ID videa s řetězcem dotazu. Například in ?id=1https://localhost:5001/Movies/Details?id=1.
Přidání šablony trasy
Aktualizujte stránky Upravit, Podrobnosti a Odstranit Razor tak, aby používaly {id:int} šablonu trasy. Změňte direktivu stránky pro každou z těchto stránek na @page@page "{id:int}". Spusťte aplikaci a pak zobrazte zdroj.
Vygenerovaný kód HTML přidá ID do části cesty adresy URL:
<td>
<a href="/Movies/Edit/1">Edit</a> |
<a href="/Movies/Details/1">Details</a> |
<a href="/Movies/Delete/1">Delete</a>
</td>
Požadavek na stránku se šablonou {id:int} trasy, která neobsahuje celé číslo, vrátí chybu HTTP 404 (nenalezena). Například https://localhost:5001/Movies/Details vrátí chybu 404. Pokud chcete nastavit ID jako volitelné, připojte k omezení trasy symbol ?:
@page "{id:int?}"
Otestujte chování @page "{id:int?}":
- Nastavte direktivu
Pages/Movies/Details.cshtmlstránky na@page "{id:int?}"hodnotu . - Nastavte zarážku v
public async Task<IActionResult> OnGetAsync(int? id), vPages/Movies/Details.cshtml.cs. - Přejděte na
https://localhost:5001/Movies/Details/.
S direktivou @page "{id:int}" se zarážka nikdy nedostane. Směrovací modul vrátí http 404. Using @page "{id:int?}", OnGetAsync metoda vrátí 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();
}
Kontrola zpracování výjimek souběžnosti
Zkontrolujte metodu OnPostAsyncPages/Movies/Edit.cshtml.cs v souboru:
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);
}
Předchozí kód zjistí výjimky souběžnosti, když jeden klient odstraní video a ostatní klienty publikují změny videa.
Postup otestování catch bloku:
- Nastavte zarážku na
catch (DbUpdateConcurrencyException). - Vyberte Upravit pro film, proveďte změny, ale nezadávejte uložit.
- V jiném okně prohlížeče vyberte odkaz Odstranit pro stejný film a pak video odstraňte.
- V předchozím okně prohlížeče publikujte změny videa.
Produkční kód může chtít zjistit konflikty souběžnosti. Další informace najdete v tématu Zpracování konfliktů souběžnosti.
Publikování a kontrola vazby
Pages/Movies/Edit.cshtml.cs Prozkoumejte soubor:
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);
}
Při provedení požadavku HTTP GET na stránku Filmy/Úpravy, například https://localhost:5001/Movies/Edit/3:
- Metoda
OnGetAsyncnačte film z databáze a vrátí metoduPage. - Metoda
PagevykreslíPages/Movies/Edit.cshtmlRazor Stránku. SouborPages/Movies/Edit.cshtmlobsahuje direktivu@model RazorPagesMovie.Pages.Movies.EditModelmodelu, která zpřístupňuje filmový model na stránce. - Formulář Upravit se zobrazí s hodnotami z filmu.
Když se publikuje stránka Movies/Edit:
Hodnoty formuláře na stránce jsou vázány na
Movievlastnost. Atribut[BindProperty]umožňuje vazbu modelu.[BindProperty] public Movie Movie { get; set; }Pokud jsou ve stavu modelu chyby,
ReleaseDatenapříklad nelze převést na datum, formulář se znovu zobrazí s odeslanými hodnotami.Pokud neexistují žádné chyby modelu, film se uloží.
Metody HTTP GET na stránkách Index, Create a Delete Razor se řídí podobným vzorem. Metoda HTTP POST OnPostAsync na create Razor page se řídí podobným vzorem OnPostAsync jako metoda v Edit Razor Page.
Další kroky
Vygenerovaná filmová aplikace má dobrý začátek, ale prezentace není ideální. Datum vydání by mělo být dvě slova– Datum vydání.
Aktualizace vygenerovaného kódu
Aktualizujte Models/Movie.cs následujícím zvýrazněným kódem:
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; }
}
}
V předchozím kódu:
- Datová
[Column(TypeName = "decimal(18, 2)")]poznámka umožňuje entity Framework Core správně mapovatPricena měnu v databázi. Další informace naleznete v tématu Datové typy. - Atribut [Display] určuje zobrazovaný název pole. V předchozím kódu místo releaseDate zadejte datum vydání.
- Atribut [DataType] určuje typ dat (
Date). Informace o čase uložené v poli se nezobrazují.
DataAnnotations najdete v dalším kurzu.
Přejděte na Stránky nebo filmy a najeďte myší na odkaz Upravit a zobrazte cílovou adresu URL.
Odkazy Upravit, Podrobnosti a Odstranit jsou generovány pomocným pomocníkem značky ukotvení v Pages/Movies/Index.cshtml souboru.
@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>
Pomocné rutiny značek umožňují, aby se kód na straně serveru v souborech Razor podílel na vytváření a vykreslování elementů HTML.
V předchozím kódu pomocník značky ukotvení dynamicky generuje hodnotu atributu HTML href ze Razor stránky (trasa je relativní), identifikátor asp-pagetrasyasp-route-id (). Další informace najdete v tématu Generování adres URL pro stránky.
K prozkoumání vygenerované značky použijte zdroj zobrazení z prohlížeče. Část vygenerovaného kódu HTML je znázorněná níže:
<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>
Dynamicky generované odkazy předávají ID videa s řetězcem dotazu. Například in ?id=1https://localhost:5001/Movies/Details?id=1.
Přidání šablony trasy
Aktualizujte stránky Upravit, Podrobnosti a Odstranit Razor tak, aby používaly {id:int} šablonu trasy. Změňte direktivu stránky pro každou z těchto stránek na @page@page "{id:int}". Spusťte aplikaci a pak zobrazte zdroj.
Vygenerovaný kód HTML přidá ID do části cesty adresy URL:
<td>
<a href="/Movies/Edit/1">Edit</a> |
<a href="/Movies/Details/1">Details</a> |
<a href="/Movies/Delete/1">Delete</a>
</td>
Požadavek na stránku se šablonou {id:int} trasy, která neobsahuje celé číslo, vrátí chybu HTTP 404 (nenalezena). Například https://localhost:5001/Movies/Details vrátí chybu 404. Pokud chcete nastavit ID jako volitelné, připojte k omezení trasy symbol ?:
@page "{id:int?}"
Otestujte chování @page "{id:int?}":
- Nastavte direktivu
Pages/Movies/Details.cshtmlstránky na@page "{id:int?}"hodnotu . - Nastavte zarážku v
public async Task<IActionResult> OnGetAsync(int? id), vPages/Movies/Details.cshtml.cs. - Přejděte na
https://localhost:5001/Movies/Details/.
S direktivou @page "{id:int}" se zarážka nikdy nedostane. Směrovací modul vrátí http 404. Using @page "{id:int?}", OnGetAsync metoda vrátí 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();
}
Kontrola zpracování výjimek souběžnosti
Zkontrolujte metodu OnPostAsyncPages/Movies/Edit.cshtml.cs v souboru:
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();
}
Předchozí kód zjistí výjimky souběžnosti, když jeden klient odstraní video a ostatní klienty publikují změny videa. Předchozí kód nezjistí konflikty, ke kterým dochází kvůli dvěma nebo více klientům, kteří současně upravují stejný film. V tomto případě se úpravy více klientů použijí v pořadí, v jakém SaveChanges se volají, a úpravy, které se použijí později, mohou přepsat dřívější úpravy zastaralými hodnotami.
Postup otestování catch bloku:
- Nastavte zarážku na
catch (DbUpdateConcurrencyException). - Vyberte Upravit pro film, proveďte změny, ale nezadávejte uložit.
- V jiném okně prohlížeče vyberte odkaz Odstranit pro stejný film a pak video odstraňte.
- V předchozím okně prohlížeče publikujte změny videa.
Produkční kód může chtít zjistit další konflikty souběžnosti, jako je například několik klientů, kteří upravují entitu najednou. Další informace najdete v tématu Zpracování konfliktů souběžnosti.
Publikování a kontrola vazby
Pages/Movies/Edit.cshtml.cs Prozkoumejte soubor:
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();
}
Při provedení požadavku HTTP GET na stránku Filmy/Úpravy, například https://localhost:5001/Movies/Edit/3:
- Metoda
OnGetAsyncnačte film z databáze a vrátí metoduPage. - Metoda
PagevykreslíPages/Movies/Edit.cshtmlRazor Stránku. SouborPages/Movies/Edit.cshtmlobsahuje direktivu@model RazorPagesMovie.Pages.Movies.EditModelmodelu, která zpřístupňuje filmový model na stránce. - Formulář Upravit se zobrazí s hodnotami z filmu.
Když se publikuje stránka Movies/Edit:
Hodnoty formuláře na stránce jsou vázány na
Movievlastnost. Atribut[BindProperty]umožňuje vazbu modelu.[BindProperty] public Movie Movie { get; set; }Pokud jsou ve stavu modelu chyby,
ReleaseDatenapříklad nelze převést na datum, formulář se znovu zobrazí s odeslanými hodnotami.Pokud neexistují žádné chyby modelu, film se uloží.
Metody HTTP GET na stránkách Index, Create a Delete Razor se řídí podobným vzorem. Metoda HTTP POST OnPostAsync na create Razor page se řídí podobným vzorem OnPostAsync jako metoda v Edit Razor Page.
Další kroky
Vygenerovaná filmová aplikace má dobrý začátek, ale prezentace není ideální. Datum vydání by mělo být dvě slova– Datum vydání.
Aktualizace vygenerovaného kódu
Models/Movie.cs Otevřete soubor a přidejte zvýrazněné řádky uvedené v následujícím kódu:
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; }
}
}
V předchozím kódu:
- Datová
[Column(TypeName = "decimal(18, 2)")]poznámka umožňuje entity Framework Core správně mapovatPricena měnu v databázi. Další informace naleznete v tématu Datové typy. - Atribut [Display] určuje zobrazovaný název pole. V předchozím kódu místo releaseDate zadejte datum vydání.
- Atribut [DataType] určuje typ dat (
Date). Informace o čase uložené v poli se nezobrazují.
DataAnnotations najdete v dalším kurzu.
Přejděte na Stránky nebo filmy a najeďte myší na odkaz Upravit a zobrazte cílovou adresu URL.
Odkazy Upravit, Podrobnosti a Odstranit jsou generovány pomocným pomocníkem značky ukotvení v Pages/Movies/Index.cshtml souboru.
@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>
Pomocné rutiny značek umožňují, aby se kód na straně serveru v souborech Razor podílel na vytváření a vykreslování elementů HTML.
V předchozím kódu pomocník značky ukotvení dynamicky generuje hodnotu atributu HTML href ze Razor stránky (trasa je relativní), identifikátor asp-pagetrasyasp-route-id (). Další informace najdete v tématu Generování adres URL pro stránky.
K prozkoumání vygenerované značky použijte zdroj zobrazení z prohlížeče. Část vygenerovaného kódu HTML je znázorněná níže:
<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>
Dynamicky generované odkazy předávají ID videa s řetězcem dotazu. Například in ?id=1https://localhost:5001/Movies/Details?id=1.
Přidání šablony trasy
Aktualizujte stránky Upravit, Podrobnosti a Odstranit Razor tak, aby používaly {id:int} šablonu trasy. Změňte direktivu stránky pro každou z těchto stránek na @page@page "{id:int}". Spusťte aplikaci a pak zobrazte zdroj.
Vygenerovaný kód HTML přidá ID do části cesty adresy URL:
<td>
<a href="/Movies/Edit/1">Edit</a> |
<a href="/Movies/Details/1">Details</a> |
<a href="/Movies/Delete/1">Delete</a>
</td>
Požadavek na stránku se šablonou {id:int} trasy, která neobsahuje celé číslo, vrátí chybu HTTP 404 (nenalezena). Například https://localhost:5001/Movies/Details vrátí chybu 404. Pokud chcete nastavit ID jako volitelné, připojte k omezení trasy symbol ?:
@page "{id:int?}"
Otestujte chování @page "{id:int?}":
- Nastavte direktivu
Pages/Movies/Details.cshtmlstránky na@page "{id:int?}"hodnotu . - Nastavte zarážku v
public async Task<IActionResult> OnGetAsync(int? id), vPages/Movies/Details.cshtml.cs. - Přejděte na
https://localhost:5001/Movies/Details/.
S direktivou @page "{id:int}" se zarážka nikdy nedostane. Směrovací modul vrátí http 404. Using @page "{id:int?}", OnGetAsync metoda vrátí 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();
}
Kontrola zpracování výjimek souběžnosti
Zkontrolujte metodu OnPostAsyncPages/Movies/Edit.cshtml.cs v souboru:
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);
}
Předchozí kód zjistí výjimky souběžnosti, když jeden klient odstraní video a ostatní klienty publikují změny videa.
Postup otestování catch bloku:
- Nastavte zarážku na
catch (DbUpdateConcurrencyException). - Vyberte Upravit pro film, proveďte změny, ale nezadávejte uložit.
- V jiném okně prohlížeče vyberte odkaz Odstranit pro stejný film a pak video odstraňte.
- V předchozím okně prohlížeče publikujte změny videa.
Produkční kód může chtít zjistit konflikty souběžnosti. Další informace najdete v tématu Zpracování konfliktů souběžnosti.
Publikování a kontrola vazby
Pages/Movies/Edit.cshtml.cs Prozkoumejte soubor:
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);
}
Při provedení požadavku HTTP GET na stránku Filmy/Úpravy, například https://localhost:5001/Movies/Edit/3:
- Metoda
OnGetAsyncnačte film z databáze a vrátí metoduPage. - Metoda
PagevykreslíPages/Movies/Edit.cshtmlRazor Stránku. SouborPages/Movies/Edit.cshtmlobsahuje direktivu@model RazorPagesMovie.Pages.Movies.EditModelmodelu, která zpřístupňuje filmový model na stránce. - Formulář Upravit se zobrazí s hodnotami z filmu.
Když se publikuje stránka Movies/Edit:
Hodnoty formuláře na stránce jsou vázány na
Movievlastnost. Atribut[BindProperty]umožňuje vazbu modelu.[BindProperty] public Movie Movie { get; set; }Pokud jsou ve stavu modelu chyby,
ReleaseDatenapříklad nelze převést na datum, formulář se znovu zobrazí s odeslanými hodnotami.Pokud neexistují žádné chyby modelu, film se uloží.
Metody HTTP GET na stránkách Index, Create a Delete Razor se řídí podobným vzorem. Metoda HTTP POST OnPostAsync na create Razor page se řídí podobným vzorem OnPostAsync jako metoda v Edit Razor Page.