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 ve verzi .NET 10 tohoto článku.
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.