Část 5– aktualizace vygenerovaných stránek v aplikaci ASP.NET Core
Poznámka:
Toto není nejnovější verze tohoto článku. Aktuální verzi najdete ve verzi .NET 8 tohoto článku.
Upozorňující
Tato verze ASP.NET Core se už nepodporuje. Další informace najdete v tématu .NET a .NET Core Zásady podpory. Aktuální verzi najdete ve verzi .NET 8 tohoto článku.
Důležité
Tyto informace se týkají předběžného vydání produktu, který může být podstatně změněn před komerčním vydáním. Microsoft neposkytuje žádné záruky, výslovné ani předpokládané, týkající se zde uváděných informací.
Aktuální verzi najdete ve verzi .NET 8 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ě mapovatPrice
na 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 Date
ReleaseDate
. - 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-page
trasyasp-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=1
https://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.cshtml
strá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 OnPostAsync
Pages/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
OnGetAsync
načte film z databáze a vrátí metoduPage
. - Metoda
Page
vykreslíPages/Movies/Edit.cshtml
Razor Stránku. SouborPages/Movies/Edit.cshtml
obsahuje direktivu@model RazorPagesMovie.Pages.Movies.EditModel
modelu, 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
Movie
vlastnost. Atribut[BindProperty]
umožňuje vazbu modelu.[BindProperty] public Movie Movie { get; set; }
Pokud jsou ve stavu modelu chyby,
ReleaseDate
napří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ě mapovatPrice
na 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 Date
ReleaseDate
. - 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-page
trasyasp-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=1
https://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.cshtml
strá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 OnPostAsync
Pages/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
OnGetAsync
načte film z databáze a vrátí metoduPage
. - Metoda
Page
vykreslíPages/Movies/Edit.cshtml
Razor Stránku. SouborPages/Movies/Edit.cshtml
obsahuje direktivu@model RazorPagesMovie.Pages.Movies.EditModel
modelu, 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
Movie
vlastnost. Atribut[BindProperty]
umožňuje vazbu modelu.[BindProperty] public Movie Movie { get; set; }
Pokud jsou ve stavu modelu chyby,
ReleaseDate
napří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ě mapovatPrice
na 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 Date
ReleaseDate
. - 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-page
trasyasp-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=1
https://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.cshtml
strá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 OnPostAsync
Pages/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
OnGetAsync
načte film z databáze a vrátí metoduPage
. - Metoda
Page
vykreslíPages/Movies/Edit.cshtml
Razor Stránku. SouborPages/Movies/Edit.cshtml
obsahuje direktivu@model RazorPagesMovie.Pages.Movies.EditModel
modelu, 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
Movie
vlastnost. Atribut[BindProperty]
umožňuje vazbu modelu.[BindProperty] public Movie Movie { get; set; }
Pokud jsou ve stavu modelu chyby,
ReleaseDate
napří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ě mapovatPrice
na 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-page
trasyasp-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=1
https://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.cshtml
strá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 OnPostAsync
Pages/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
OnGetAsync
načte film z databáze a vrátí metoduPage
. - Metoda
Page
vykreslíPages/Movies/Edit.cshtml
Razor Stránku. SouborPages/Movies/Edit.cshtml
obsahuje direktivu@model RazorPagesMovie.Pages.Movies.EditModel
modelu, 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
Movie
vlastnost. Atribut[BindProperty]
umožňuje vazbu modelu.[BindProperty] public Movie Movie { get; set; }
Pokud jsou ve stavu modelu chyby,
ReleaseDate
napří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ě mapovatPrice
na 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-page
trasyasp-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=1
https://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.cshtml
strá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 OnPostAsync
Pages/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
OnGetAsync
načte film z databáze a vrátí metoduPage
. - Metoda
Page
vykreslíPages/Movies/Edit.cshtml
Razor Stránku. SouborPages/Movies/Edit.cshtml
obsahuje direktivu@model RazorPagesMovie.Pages.Movies.EditModel
modelu, 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
Movie
vlastnost. Atribut[BindProperty]
umožňuje vazbu modelu.[BindProperty] public Movie Movie { get; set; }
Pokud jsou ve stavu modelu chyby,
ReleaseDate
napří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.