Část 3, vygenerované Razor stránky v ASP.NET Core

Poznámka:

Toto není nejnovější verze tohoto článku. 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.

Autor: Rick Anderson

Tento kurz prozkoumá Razor stránky vytvořené generováním uživatelského rozhraní v předchozím kurzu.

Stránky Vytvořit, Odstranit, Podrobnosti a Upravit

Pages/Movies/Index.cshtml.cs Prozkoumejte model stránky:

using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using RazorPagesMovie.Models;

namespace RazorPagesMovie.Pages.Movies;

public class IndexModel : PageModel
{
    private readonly RazorPagesMovie.Data.RazorPagesMovieContext _context;

    public IndexModel(RazorPagesMovie.Data.RazorPagesMovieContext context)
    {
        _context = context;
    }

    public IList<Movie> Movie { get;set; }  = default!;

    public async Task OnGetAsync()
    {
        if (_context.Movie != null)
        {
            Movie = await _context.Movie.ToListAsync();
        }
    }
}

Razor Stránky jsou odvozeny z PageModel. Podle konvence je odvozená PageModel třída pojmenována PageNameModel. Například indexová stránka má název IndexModel.

Konstruktor pomocí injektáže závislostí přidá RazorPagesMovieContext na stránku:

public class IndexModel : PageModel
{
    private readonly RazorPagesMovie.Data.RazorPagesMovieContext _context;

    public IndexModel(RazorPagesMovie.Data.RazorPagesMovieContext context)
    {
        _context = context;
    }

Další informace o asynchronním programování pomocí Entity Frameworku najdete v asynchronním kódu .

GET Při požadavku na stránku OnGetAsync vrátí metoda seznam filmů na Razor stránku. Razor Na stránce OnGetAsync nebo OnGet je volána k inicializaci stavu stránky. V tomto případě OnGetAsync získá seznam filmů a zobrazí je.

Pokud OnGet se vrátí void nebo OnGetAsync vrátí Task, nepoužije se žádný návratový příkaz. Podívejte se například na Privacy stránku:

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace RazorPagesMovie.Pages
{
    public class PrivacyModel : PageModel
    {
        private readonly ILogger<PrivacyModel> _logger;

        public PrivacyModel(ILogger<PrivacyModel> logger)
        {
            _logger = logger;
        }

        public void OnGet()
        {
        }
    }
}

Pokud je IActionResult návratový typ nebo Task<IActionResult>, musí být zadán návratový příkaz. Například Pages/Movies/Create.cshtml.cs OnPostAsync metoda:

public async Task<IActionResult> OnPostAsync()
{
  if (!ModelState.IsValid)
    {
        return Page();
    }

    _context.Movie.Add(Movie);
    await _context.SaveChangesAsync();

    return RedirectToPage("./Index");
}

Pages/Movies/Index.cshtmlRazor Prozkoumejte stránku:

@page
@model RazorPagesMovie.Pages.Movies.IndexModel

@{
    ViewData["Title"] = "Index";
}

<h1>Index</h1>

<p>
    <a asp-page="Create">Create New</a>
</p>
<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].Title)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].ReleaseDate)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].Genre)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].Price)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
@foreach (var item in Model.Movie) {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.Title)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.ReleaseDate)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Genre)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Price)
            </td>
            <td>
                <a asp-page="./Edit" asp-route-id="@item.Id">Edit</a> |
                <a asp-page="./Details" asp-route-id="@item.Id">Details</a> |
                <a asp-page="./Delete" asp-route-id="@item.Id">Delete</a>
            </td>
        </tr>
}
    </tbody>
</table>

Razor může přejít z HTML do jazyka C# nebo do Razorkódu specifického pro konkrétní značky. @ Když za symbolem následuje Razor vyhrazené klíčové slovo, přejde do Razorkódu specifického pro konkrétní kód, jinak přejde do jazyka C#.

Direktiva @page

Direktiva @pageRazor vytvoří soubor akci MVC, což znamená, že může zpracovávat požadavky. Direktiva @page musí být první direktivou Razor na stránce. @page a @model představují příklady přechodu na Razorkonkrétní značky. Další informace najdete Razor v syntaxi .

Direktiva @model

@page
@model RazorPagesMovie.Pages.Movies.IndexModel

Direktiva @model určuje typ modelu předaného stránce Razor . V předchozím příkladu @model zpřístupňuje řádek odvozenou PageModel třídu stránce Razor . Model se používá v pomocných rutinách @Html.DisplayNameFor@Html.DisplayFor HTML na stránce.

Prozkoumejte výraz lambda použitý v následujícím pomocníkovi HTML:

@Html.DisplayNameFor(model => model.Movie[0].Title)

Pomocník DisplayNameFor HTML zkontroluje Title vlastnost odkazovanou ve výrazu lambda a určí zobrazovaný název. Výraz lambda se kontroluje místo vyhodnocení. To znamená, že neexistuje žádné narušení přístupu, pokud model, model.Movienebo je nebo model.Movie[0] je null prázdné. Při vyhodnocování výrazu lambda, například pomocí @Html.DisplayFor(modelItem => item.Title), hodnoty vlastností modelu jsou vyhodnoceny.

Stránka rozložení

Vyberte nabídku odkazy RazorPagesMovie, Homea Privacy. Každá stránka zobrazuje stejné rozložení nabídky. V souboru se implementuje Pages/Shared/_Layout.cshtml rozložení nabídky.

Otevřete a prozkoumejte Pages/Shared/_Layout.cshtml soubor.

Šablony rozložení umožňují, aby rozložení kontejneru HTML bylo:

  • Zadané na jednom místě.
  • Používá se na více stránkách na webu.

@RenderBody() Najděte řádek. RenderBody je zástupný symbol, kde se všechna zobrazení specifická pro stránky zobrazují, zabalená na stránce rozložení. Vyberte například Privacy odkaz a Pages/Privacy.cshtml zobrazení se vykreslí RenderBody uvnitř metody.

ViewData a rozložení

Vezměte v úvahu Pages/Movies/Index.cshtml následující kód ze souboru:

@page
@model RazorPagesMovie.Pages.Movies.IndexModel

@{
    ViewData["Title"] = "Index";
}

Předchozí zvýrazněný kód je příkladem Razor přechodu na C#. } A { znaky ohraničují blok kódu jazyka C#.

Základní PageModel třída obsahuje vlastnost slovníku ViewData , která lze použít k předávání dat do zobrazení. Objekty se přidají do slovníku ViewDatapomocí vzoru klíč-hodnota. V předchozí ukázce se Title vlastnost přidá do slovníku ViewData .

Vlastnost Title se používá v Pages/Shared/_Layout.cshtml souboru. Následující kód ukazuje několik prvních řádků _Layout.cshtml souboru.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - RazorPagesMovie</title>
    <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
    <link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
    <link rel="stylesheet" href="~/RazorPagesMovie.styles.css" asp-append-version="true" />

Aktualizace rozložení

  1. <title> Změňte prvek v Pages/Shared/_Layout.cshtml souboru tak, aby se místo RazorPagesMovie zobrazoval film.

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>@ViewData["Title"] - Movie</title>
    
  2. V souboru vyhledejte následující prvek ukotvení Pages/Shared/_Layout.cshtml .

    <a class="navbar-brand" asp-area="" asp-page="/Index">RazorPagesMovie</a>
    
  3. Nahraďte předchozí prvek následujícím kódem:

    <a class="navbar-brand" asp-page="/Movies/Index">RpMovie</a>
    

    Předchozí prvek ukotvení je pomocník značky. V tomto případě se jedná o pomocnou rutinu značky ukotvení. Atribut asp-page="/Movies/Index" Pomocné rutiny značky a hodnota vytvoří odkaz na /Movies/IndexRazor stránku. Hodnota asp-area atributu je prázdná, takže se tato oblast v odkazu nepoužívá. Další informace najdete v části Oblasti .

  4. Uložte změny a otestujte aplikaci výběrem odkazu RpMovie . Pokud máte nějaké problémy, podívejte se na soubor _Layout.cshtml na GitHubu.

  5. Otestujte odkazy Home, RpMovie, Vytvořit, Upravit a Odstranit . Každá stránka nastaví název, který můžete vidět na kartě prohlížeče. Při vytvoření záložky stránky se název použije pro záložku.

Poznámka:

Do pole pravděpodobně nebudete moct zadávat desetinné čárky Price . Pokud chcete podporovat ověřování jQuery pro neanglické národní prostředí používající čárku (",") pro desetinnou čárku a jiné formáty kalendářních dat než v angličtině, musíte provést kroky ke globalizaci aplikace. Pokyny k přidání desetinných čárk najdete v tomto problému Na GitHubu 4076 .

Vlastnost Layout je nastavena Pages/_ViewStart.cshtml v souboru:

@{
    Layout = "_Layout";
}

Předchozí revize nastaví soubor rozložení pro Pages/Shared/_Layout.cshtml všechny soubory ve složce PagesRazor. Další informace najdete v tématu Rozložení .

Model vytvořit stránku

Pages/Movies/Create.cshtml.cs Prozkoumejte model stránky:

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using RazorPagesMovie.Models;

namespace RazorPagesMovie.Pages.Movies
{
    public class CreateModel : PageModel
    {
        private readonly RazorPagesMovie.Data.RazorPagesMovieContext _context;

        public CreateModel(RazorPagesMovie.Data.RazorPagesMovieContext context)
        {
            _context = context;
        }

        public IActionResult OnGet()
        {
            return Page();
        }

        [BindProperty]
        public Movie Movie { get; set; } = default!;
        

        // To protect from overposting attacks, see https://aka.ms/RazorPagesCRUD
        public async Task<IActionResult> OnPostAsync()
        {
          if (!ModelState.IsValid || _context.Movie == null || Movie == null)
            {
                return Page();
            }

            _context.Movie.Add(Movie);
            await _context.SaveChangesAsync();

            return RedirectToPage("./Index");
        }
    }
}

Metoda OnGet inicializuje jakýkoli stav potřebný pro stránku. Stránka Vytvořit nemá k inicializaci žádný stav, takže Page se vrátí. V pozdější části kurzu se zobrazí příklad OnGet inicializace stavu. Metoda Page vytvoří PageResult objekt, který vykreslí Create.cshtml stránku.

Vlastnost Movie používá atribut [BindProperty] k vyjádření souhlasu s vazbou modelu. Při vytvoření formuláře publikuje hodnoty formuláře, ASP.NET Core runtime vytvoří vazbu odeslaných hodnot k Movie modelu.

Metoda OnPostAsync se spustí, když stránka publikuje data formuláře:

public async Task<IActionResult> OnPostAsync()
{
  if (!ModelState.IsValid)
    {
        return Page();
    }

    _context.Movie.Add(Movie);
    await _context.SaveChangesAsync();

    return RedirectToPage("./Index");
}

Pokud dojde k nějakým chybám modelu, formulář se znovu zobrazí spolu s publikovanými daty formuláře. Většinu chyb modelu lze zachytit na straně klienta před odesláním formuláře. Příkladem chyby modelu je zaúčtování hodnoty pro pole kalendářního data, které nelze převést na datum. Ověření na straně klienta a ověření modelu se probírá později v tomto kurzu.

Pokud neexistují žádné chyby modelu:

  • Data se uloží.
  • Prohlížeč se přesměruje na stránku Index.

Stránka Vytvořit Razor

Prozkoumání stránkového Pages/Movies/Create.cshtmlRazor souboru:

@page
@model RazorPagesMovie.Pages.Movies.CreateModel

@{
    ViewData["Title"] = "Create";
}

<h1>Create</h1>

<h4>Movie</h4>
<hr />
<div class="row">
    <div class="col-md-4">
        <form method="post">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <div class="form-group">
                <label asp-for="Movie.Title" class="control-label"></label>
                <input asp-for="Movie.Title" class="form-control" />
                <span asp-validation-for="Movie.Title" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Movie.ReleaseDate" class="control-label"></label>
                <input asp-for="Movie.ReleaseDate" class="form-control" />
                <span asp-validation-for="Movie.ReleaseDate" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Movie.Genre" class="control-label"></label>
                <input asp-for="Movie.Genre" class="form-control" />
                <span asp-validation-for="Movie.Genre" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Movie.Price" class="control-label"></label>
                <input asp-for="Movie.Price" class="form-control" />
                <span asp-validation-for="Movie.Price" class="text-danger"></span>
            </div>
            <div class="form-group">
                <input type="submit" value="Create" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>

<div>
    <a asp-page="Index">Back to List</a>
</div>

@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}

Visual Studio zobrazí následující značky v odlišném tučném písmu použitém pro pomocné rutiny značek:

  • <form method="post">
  • <div asp-validation-summary="ModelOnly" class="text-danger"></div>
  • <label asp-for="Movie.Title" class="control-label"></label>
  • <input asp-for="Movie.Title" class="form-control" />
  • <span asp-validation-for="Movie.Title" class="text-danger"></span>

Zobrazení VS17 stránky Create.cshtml

Prvek <form method="post"> je pomocným rutinou značky formuláře. Pomocná rutina značky formuláře automaticky obsahuje antiforgery token.

Modul generování uživatelského rozhraní vytvoří Razor kód pro každé pole v modelu s výjimkou ID, podobně jako v následujícím příkladu:

<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
    <label asp-for="Movie.Title" class="control-label"></label>
    <input asp-for="Movie.Title" class="form-control" />
    <span asp-validation-for="Movie.Title" class="text-danger"></span>
</div>

Pomocné rutiny ověřovacích značek (<div asp-validation-summary a <span asp-validation-for) zobrazují chyby ověření. Ověřování je podrobněji popsáno dále v této sérii.

Pomocník značky popisku (<label asp-for="Movie.Title" class="control-label"></label>) vygeneruje popisek popis a [for] atribut pro Title vlastnost.

Pomocný rutina vstupní značky (<input asp-for="Movie.Title" class="form-control">) používá atributy DataAnnotations a vytváří atributy HTML potřebné pro ověřování jQuery na straně klienta.

Další informace o pomocných rutinách značek, jako <form method="post">je například , naleznete v tématu Pomocné rutiny značek v ASP.NET Core.

Další kroky

Stránky Vytvořit, Odstranit, Podrobnosti a Upravit

Pages/Movies/Index.cshtml.cs Prozkoumejte model stránky:

using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using RazorPagesMovie.Models;

namespace RazorPagesMovie.Pages.Movies;

public class IndexModel : PageModel
{
    private readonly RazorPagesMovie.Data.RazorPagesMovieContext _context;

    public IndexModel(RazorPagesMovie.Data.RazorPagesMovieContext context)
    {
        _context = context;
    }

    public IList<Movie> Movie { get;set; }  = default!;

    public async Task OnGetAsync()
    {
        if (_context.Movie != null)
        {
            Movie = await _context.Movie.ToListAsync();
        }
    }
}

Razor Stránky jsou odvozeny z PageModel. Podle konvence je odvozená PageModel třída pojmenována PageNameModel. Například indexová stránka má název IndexModel.

Konstruktor pomocí injektáže závislostí přidá RazorPagesMovieContext na stránku:

public class IndexModel : PageModel
{
    private readonly RazorPagesMovie.Data.RazorPagesMovieContext _context;

    public IndexModel(RazorPagesMovie.Data.RazorPagesMovieContext context)
    {
        _context = context;
    }

Další informace o asynchronním programování pomocí Entity Frameworku najdete v asynchronním kódu .

GET Při požadavku na stránku OnGetAsync vrátí metoda seznam filmů na Razor stránku. Razor Na stránce OnGetAsync nebo OnGet je volána k inicializaci stavu stránky. V tomto případě OnGetAsync získá seznam filmů a zobrazí je.

Pokud OnGet se vrátí void nebo OnGetAsync vrátí Task, nepoužije se žádný návratový příkaz. Podívejte se například na Privacy stránku:

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace RazorPagesMovie.Pages
{
    public class PrivacyModel : PageModel
    {
        private readonly ILogger<PrivacyModel> _logger;

        public PrivacyModel(ILogger<PrivacyModel> logger)
        {
            _logger = logger;
        }

        public void OnGet()
        {
        }
    }
}

Pokud je IActionResult návratový typ nebo Task<IActionResult>, musí být zadán návratový příkaz. Například Pages/Movies/Create.cshtml.cs OnPostAsync metoda:

public async Task<IActionResult> OnPostAsync()
{
  if (!ModelState.IsValid)
    {
        return Page();
    }

    _context.Movie.Add(Movie);
    await _context.SaveChangesAsync();

    return RedirectToPage("./Index");
}

Pages/Movies/Index.cshtmlRazor Prozkoumejte stránku:

@page
@model RazorPagesMovie.Pages.Movies.IndexModel

@{
    ViewData["Title"] = "Index";
}

<h1>Index</h1>

<p>
    <a asp-page="Create">Create New</a>
</p>
<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].Title)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].ReleaseDate)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].Genre)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].Price)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
@foreach (var item in Model.Movie) {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.Title)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.ReleaseDate)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Genre)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Price)
            </td>
            <td>
                <a asp-page="./Edit" asp-route-id="@item.Id">Edit</a> |
                <a asp-page="./Details" asp-route-id="@item.Id">Details</a> |
                <a asp-page="./Delete" asp-route-id="@item.Id">Delete</a>
            </td>
        </tr>
}
    </tbody>
</table>

Razor může přejít z HTML do jazyka C# nebo do Razorkódu specifického pro konkrétní značky. @ Když za symbolem následuje Razor vyhrazené klíčové slovo, přejde do Razorkódu specifického pro konkrétní kód, jinak přejde do jazyka C#.

Direktiva @page

Direktiva @pageRazor vytvoří soubor akci MVC, což znamená, že může zpracovávat požadavky. Direktiva @page musí být první direktivou Razor na stránce. @page a @model představují příklady přechodu na Razorkonkrétní značky. Další informace najdete Razor v syntaxi .

Direktiva @model

@page
@model RazorPagesMovie.Pages.Movies.IndexModel

Direktiva @model určuje typ modelu předaného stránce Razor . V předchozím příkladu @model zpřístupňuje řádek odvozenou PageModel třídu stránce Razor . Model se používá v pomocných rutinách @Html.DisplayNameFor@Html.DisplayFor HTML na stránce.

Prozkoumejte výraz lambda použitý v následujícím pomocníkovi HTML:

@Html.DisplayNameFor(model => model.Movie[0].Title)

Pomocník DisplayNameFor HTML zkontroluje Title vlastnost odkazovanou ve výrazu lambda a určí zobrazovaný název. Výraz lambda se kontroluje místo vyhodnocení. To znamená, že neexistuje žádné narušení přístupu, pokud model, model.Movienebo je nebo model.Movie[0] je null prázdné. Při vyhodnocování výrazu lambda, například pomocí @Html.DisplayFor(modelItem => item.Title), hodnoty vlastností modelu jsou vyhodnoceny.

Stránka rozložení

Vyberte nabídku odkazy RazorPagesMovie, Homea Privacy. Každá stránka zobrazuje stejné rozložení nabídky. V souboru se implementuje Pages/Shared/_Layout.cshtml rozložení nabídky.

Otevřete a prozkoumejte Pages/Shared/_Layout.cshtml soubor.

Šablony rozložení umožňují, aby rozložení kontejneru HTML bylo:

  • Zadané na jednom místě.
  • Používá se na více stránkách na webu.

@RenderBody() Najděte řádek. RenderBody je zástupný symbol, kde se všechna zobrazení specifická pro stránky zobrazují, zabalená na stránce rozložení. Vyberte například Privacy odkaz a Pages/Privacy.cshtml zobrazení se vykreslí RenderBody uvnitř metody.

ViewData a rozložení

Vezměte v úvahu Pages/Movies/Index.cshtml následující kód ze souboru:

@page
@model RazorPagesMovie.Pages.Movies.IndexModel

@{
    ViewData["Title"] = "Index";
}

Předchozí zvýrazněný kód je příkladem Razor přechodu na C#. } A { znaky ohraničují blok kódu jazyka C#.

Základní PageModel třída obsahuje vlastnost slovníku ViewData , která lze použít k předávání dat do zobrazení. Objekty se přidají do slovníku ViewDatapomocí vzoru klíč-hodnota. V předchozí ukázce se Title vlastnost přidá do slovníku ViewData .

Vlastnost Title se používá v Pages/Shared/_Layout.cshtml souboru. Následující kód ukazuje několik prvních řádků _Layout.cshtml souboru.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - RazorPagesMovie</title>
    <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
    <link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
    <link rel="stylesheet" href="~/RazorPagesMovie.styles.css" asp-append-version="true" />

Řádek @*Markup removed for brevity.*@ je Razor komentář. Na rozdíl od komentářů <!-- -->Razor HTML se komentáře do klienta neodesílají. Další informace najdete ve webové dokumentaci k MDN: Začínáme s HTML .

Aktualizace rozložení

  1. <title> Změňte prvek v Pages/Shared/_Layout.cshtml souboru tak, aby se místo RazorPagesMovie zobrazoval film.

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>@ViewData["Title"] - Movie</title>
    
  2. V souboru vyhledejte následující prvek ukotvení Pages/Shared/_Layout.cshtml .

    <a class="navbar-brand" asp-area="" asp-page="/Index">RazorPagesMovie</a>
    
  3. Nahraďte předchozí prvek následujícím kódem:

    <a class="navbar-brand" asp-page="/Movies/Index">RpMovie</a>
    

    Předchozí prvek ukotvení je pomocník značky. V tomto případě se jedná o pomocnou rutinu značky ukotvení. Atribut asp-page="/Movies/Index" Pomocné rutiny značky a hodnota vytvoří odkaz na /Movies/IndexRazor stránku. Hodnota asp-area atributu je prázdná, takže se tato oblast v odkazu nepoužívá. Další informace najdete v části Oblasti .

  4. Uložte změny a otestujte aplikaci výběrem odkazu RpMovie . Pokud máte nějaké problémy, podívejte se na soubor _Layout.cshtml na GitHubu.

  5. Otestujte odkazy Home, RpMovie, Vytvořit, Upravit a Odstranit . Každá stránka nastaví název, který můžete vidět na kartě prohlížeče. Při vytvoření záložky stránky se název použije pro záložku.

Poznámka:

Do pole pravděpodobně nebudete moct zadávat desetinné čárky Price . Pokud chcete podporovat ověřování jQuery pro neanglické národní prostředí používající čárku (",") pro desetinnou čárku a jiné formáty kalendářních dat než v angličtině, musíte provést kroky ke globalizaci aplikace. Pokyny k přidání desetinných čárk najdete v tomto problému Na GitHubu 4076 .

Vlastnost Layout je nastavena Pages/_ViewStart.cshtml v souboru:

@{
    Layout = "_Layout";
}

Předchozí revize nastaví soubor rozložení pro Pages/Shared/_Layout.cshtml všechny soubory ve složce PagesRazor. Další informace najdete v tématu Rozložení .

Model vytvořit stránku

Pages/Movies/Create.cshtml.cs Prozkoumejte model stránky:

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using RazorPagesMovie.Models;

namespace RazorPagesMovie.Pages.Movies
{
    public class CreateModel : PageModel
    {
        private readonly RazorPagesMovie.Data.RazorPagesMovieContext _context;

        public CreateModel(RazorPagesMovie.Data.RazorPagesMovieContext context)
        {
            _context = context;
        }

        public IActionResult OnGet()
        {
            return Page();
        }

        [BindProperty]
        public Movie Movie { get; set; } = default!;
        

        // To protect from overposting attacks, see https://aka.ms/RazorPagesCRUD
        public async Task<IActionResult> OnPostAsync()
        {
          if (!ModelState.IsValid || _context.Movie == null || Movie == null)
            {
                return Page();
            }

            _context.Movie.Add(Movie);
            await _context.SaveChangesAsync();

            return RedirectToPage("./Index");
        }
    }
}

Metoda OnGet inicializuje jakýkoli stav potřebný pro stránku. Stránka Vytvořit nemá k inicializaci žádný stav, takže Page se vrátí. V pozdější části kurzu se zobrazí příklad OnGet inicializace stavu. Metoda Page vytvoří PageResult objekt, který vykreslí Create.cshtml stránku.

Vlastnost Movie používá atribut [BindProperty] k vyjádření souhlasu s vazbou modelu. Při vytvoření formuláře publikuje hodnoty formuláře, ASP.NET Core runtime vytvoří vazbu odeslaných hodnot k Movie modelu.

Metoda OnPostAsync se spustí, když stránka publikuje data formuláře:

public async Task<IActionResult> OnPostAsync()
{
  if (!ModelState.IsValid)
    {
        return Page();
    }

    _context.Movie.Add(Movie);
    await _context.SaveChangesAsync();

    return RedirectToPage("./Index");
}

Pokud dojde k nějakým chybám modelu, formulář se znovu zobrazí spolu s publikovanými daty formuláře. Většinu chyb modelu lze zachytit na straně klienta před odesláním formuláře. Příkladem chyby modelu je zaúčtování hodnoty pro pole kalendářního data, které nelze převést na datum. Ověření na straně klienta a ověření modelu se probírá později v tomto kurzu.

Pokud neexistují žádné chyby modelu:

  • Data se uloží.
  • Prohlížeč se přesměruje na stránku Index.

Stránka Vytvořit Razor

Prozkoumání stránkového Pages/Movies/Create.cshtmlRazor souboru:

@page
@model RazorPagesMovie.Pages.Movies.CreateModel

@{
    ViewData["Title"] = "Create";
}

<h1>Create</h1>

<h4>Movie</h4>
<hr />
<div class="row">
    <div class="col-md-4">
        <form method="post">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <div class="form-group">
                <label asp-for="Movie.Title" class="control-label"></label>
                <input asp-for="Movie.Title" class="form-control" />
                <span asp-validation-for="Movie.Title" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Movie.ReleaseDate" class="control-label"></label>
                <input asp-for="Movie.ReleaseDate" class="form-control" />
                <span asp-validation-for="Movie.ReleaseDate" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Movie.Genre" class="control-label"></label>
                <input asp-for="Movie.Genre" class="form-control" />
                <span asp-validation-for="Movie.Genre" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Movie.Price" class="control-label"></label>
                <input asp-for="Movie.Price" class="form-control" />
                <span asp-validation-for="Movie.Price" class="text-danger"></span>
            </div>
            <div class="form-group">
                <input type="submit" value="Create" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>

<div>
    <a asp-page="Index">Back to List</a>
</div>

@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}

Visual Studio zobrazí následující značky v odlišném tučném písmu použitém pro pomocné rutiny značek:

  • <form method="post">
  • <div asp-validation-summary="ModelOnly" class="text-danger"></div>
  • <label asp-for="Movie.Title" class="control-label"></label>
  • <input asp-for="Movie.Title" class="form-control" />
  • <span asp-validation-for="Movie.Title" class="text-danger"></span>

Zobrazení VS17 stránky Create.cshtml

Prvek <form method="post"> je pomocným rutinou značky formuláře. Pomocná rutina značky formuláře automaticky obsahuje antiforgery token.

Modul generování uživatelského rozhraní vytvoří Razor kód pro každé pole v modelu s výjimkou ID, podobně jako v následujícím příkladu:

<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
    <label asp-for="Movie.Title" class="control-label"></label>
    <input asp-for="Movie.Title" class="form-control" />
    <span asp-validation-for="Movie.Title" class="text-danger"></span>
</div>

Pomocné rutiny ověřovacích značek (<div asp-validation-summary a <span asp-validation-for) zobrazují chyby ověření. Ověřování je podrobněji popsáno dále v této sérii.

Pomocník značky popisku (<label asp-for="Movie.Title" class="control-label"></label>) vygeneruje popisek popis a [for] atribut pro Title vlastnost.

Pomocný rutina vstupní značky (<input asp-for="Movie.Title" class="form-control">) používá atributy DataAnnotations a vytváří atributy HTML potřebné pro ověřování jQuery na straně klienta.

Další informace o pomocných rutinách značek, jako <form method="post">je například , naleznete v tématu Pomocné rutiny značek v ASP.NET Core.

Další kroky

Stránky Vytvořit, Odstranit, Podrobnosti a Upravit

Pages/Movies/Index.cshtml.cs Prozkoumejte model stránky:

using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using RazorPagesMovie.Models;

namespace RazorPagesMovie.Pages.Movies
{
    public class IndexModel : PageModel
    {
        private readonly RazorPagesMovie.Data.RazorPagesMovieContext _context;

        public IndexModel(RazorPagesMovie.Data.RazorPagesMovieContext context)
        {
            _context = context;
        }

        public IList<Movie> Movie { get;set; } = default!;

        public async Task OnGetAsync()
        {
            if (_context.Movie != null)
            {
                Movie = await _context.Movie.ToListAsync();
            }
        }
    }
}

Razor Stránky jsou odvozeny z PageModel. Podle konvence je odvozená PageModel třída pojmenována PageNameModel. Například indexová stránka má název IndexModel.

Konstruktor pomocí injektáže závislostí přidá RazorPagesMovieContext na stránku:

public class IndexModel : PageModel
{
    private readonly RazorPagesMovie.Data.RazorPagesMovieContext _context;

    public IndexModel(RazorPagesMovie.Data.RazorPagesMovieContext context)
    {
        _context = context;
    }

Další informace o asynchronním programování pomocí Entity Frameworku najdete v asynchronním kódu .

Při požadavku na stránku OnGetAsync vrátí metoda seznam filmů na Razor stránku. Razor Na stránce OnGetAsync nebo OnGet je volána k inicializaci stavu stránky. V tomto případě OnGetAsync získá seznam filmů a zobrazí je.

Pokud OnGet se vrátí void nebo OnGetAsync vrátí Task, nepoužije se žádný návratový příkaz. Podívejte se například na Privacy stránku:

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace RazorPagesMovie.Pages
{
    public class PrivacyModel : PageModel
    {
        private readonly ILogger<PrivacyModel> _logger;

        public PrivacyModel(ILogger<PrivacyModel> logger)
        {
            _logger = logger;
        }

        public void OnGet()
        {
        }
    }
}

Pokud je IActionResult návratový typ nebo Task<IActionResult>, musí být zadán návratový příkaz. Například Pages/Movies/Create.cshtml.csOnPostAsync metoda:

public async Task<IActionResult> OnPostAsync()
{
  if (!ModelState.IsValid || _context.Movie == null || Movie == null)
    {
        return Page();
    }

    _context.Movie.Add(Movie);
    await _context.SaveChangesAsync();

    return RedirectToPage("./Index");
}

Pages/Movies/Index.cshtmlRazor Prozkoumejte stránku:

@page
@model RazorPagesMovie.Pages.Movies.IndexModel

@{
    ViewData["Title"] = "Index";
}

<h1>Index</h1>

<p>
    <a asp-page="Create">Create New</a>
</p>
<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].Title)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].ReleaseDate)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].Genre)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].Price)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
@foreach (var item in Model.Movie) {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.Title)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.ReleaseDate)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Genre)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Price)
            </td>
            <td>
                <a asp-page="./Edit" asp-route-id="@item.ID">Edit</a> |
                <a asp-page="./Details" asp-route-id="@item.ID">Details</a> |
                <a asp-page="./Delete" asp-route-id="@item.ID">Delete</a>
            </td>
        </tr>
}
    </tbody>
</table>

Razor může přejít z HTML do jazyka C# nebo do Razorkódu specifického pro konkrétní značky. @ Když za symbolem následuje Razor vyhrazené klíčové slovo, přejde do Razorkódu specifického pro konkrétní kód, jinak přejde do jazyka C#.

Direktiva @page

Direktiva @pageRazor vytvoří soubor akci MVC, což znamená, že může zpracovávat požadavky. Direktiva @page musí být první direktivou Razor na stránce. @page a @model představují příklady přechodu na Razorkonkrétní značky. Další informace najdete Razor v syntaxi .

Direktiva @model

@page
@model RazorPagesMovie.Pages.Movies.IndexModel

Direktiva @model určuje typ modelu předaného stránce Razor . V předchozím příkladu @model zpřístupňuje řádek odvozenou PageModel třídu stránce Razor . Model se používá v pomocných rutinách @Html.DisplayNameFor@Html.DisplayFor HTML na stránce.

Prozkoumejte výraz lambda použitý v následujícím pomocníkovi HTML:

@Html.DisplayNameFor(model => model.Movie[0].Title)

Pomocník DisplayNameFor HTML zkontroluje Title vlastnost odkazovanou ve výrazu lambda a určí zobrazovaný název. Výraz lambda se kontroluje místo vyhodnocení. To znamená, že neexistuje žádné narušení přístupu, pokud model, model.Movienebo je nebo model.Movie[0] je null prázdné. Při vyhodnocování výrazu lambda, například pomocí @Html.DisplayFor(modelItem => item.Title), hodnoty vlastností modelu jsou vyhodnoceny.

Stránka rozložení

Vyberte nabídku odkazy RazorPagesMovie, Homea Privacy. Každá stránka zobrazuje stejné rozložení nabídky. V souboru se implementuje Pages/Shared/_Layout.cshtml rozložení nabídky.

Otevřete a prozkoumejte Pages/Shared/_Layout.cshtml soubor.

Šablony rozložení umožňují, aby rozložení kontejneru HTML bylo:

  • Zadané na jednom místě.
  • Používá se na více stránkách na webu.

@RenderBody() Najděte řádek. RenderBody je zástupný symbol, kde se všechna zobrazení specifická pro stránky zobrazují, zabalená na stránce rozložení. Vyberte například Privacy odkaz a Pages/Privacy.cshtml zobrazení se vykreslí RenderBody uvnitř metody.

ViewData a rozložení

Vezměte v úvahu Pages/Movies/Index.cshtml následující kód ze souboru:

@page
@model RazorPagesMovie.Pages.Movies.IndexModel

@{
    ViewData["Title"] = "Index";
}

Předchozí zvýrazněný kód je příkladem Razor přechodu na C#. } A { znaky ohraničují blok kódu jazyka C#.

Základní PageModel třída obsahuje vlastnost slovníku ViewData , která lze použít k předávání dat do zobrazení. Objekty se přidají do slovníku ViewDatapomocí vzoru klíč-hodnota. V předchozí ukázce se Title vlastnost přidá do slovníku ViewData .

Vlastnost Title se používá v Pages/Shared/_Layout.cshtml souboru. Následující kód ukazuje několik prvních řádků _Layout.cshtml souboru.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - RazorPagesMovie</title>

     @*Markup removed for brevity.*@
    <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />

Řádek @*Markup removed for brevity.*@ je Razor komentář. Na rozdíl od komentářů <!-- -->Razor HTML se komentáře do klienta neodesílají. Další informace najdete ve webové dokumentaci k MDN: Začínáme s HTML .

Aktualizace rozložení

  1. <title> Změňte prvek v Pages/Shared/_Layout.cshtml souboru tak, aby se místo RazorPagesMovie zobrazoval film.

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>@ViewData["Title"] - Movie</title>
    
  2. V souboru vyhledejte následující prvek ukotvení Pages/Shared/_Layout.cshtml .

    <a class="navbar-brand" asp-area="" asp-page="/Index">RazorPagesMovie</a>
    
  3. Nahraďte předchozí prvek následujícím kódem:

    <a class="navbar-brand" asp-page="/Movies/Index">RpMovie</a>
    

    Předchozí prvek ukotvení je pomocník značky. V tomto případě se jedná o pomocnou rutinu značky ukotvení. Atribut asp-page="/Movies/Index" Pomocné rutiny značky a hodnota vytvoří odkaz na /Movies/IndexRazor stránku. Hodnota asp-area atributu je prázdná, takže se tato oblast v odkazu nepoužívá. Další informace najdete v části Oblasti .

  4. Uložte změny a otestujte aplikaci výběrem odkazu RpMovie . Pokud máte nějaké problémy, podívejte se na soubor _Layout.cshtml na GitHubu.

  5. Otestujte odkazy Home, RpMovie, Vytvořit, Upravit a Odstranit . Každá stránka nastaví název, který můžete vidět na kartě prohlížeče. Při vytvoření záložky stránky se název použije pro záložku.

Poznámka:

Do pole pravděpodobně nebudete moct zadávat desetinné čárky Price . Pokud chcete podporovat ověřování jQuery pro neanglické národní prostředí používající čárku (",") pro desetinnou čárku a jiné formáty kalendářních dat než v angličtině, musíte provést kroky ke globalizaci aplikace. Pokyny k přidání desetinných čárk najdete v tomto problému Na GitHubu 4076 .

Vlastnost Layout je nastavena Pages/_ViewStart.cshtml v souboru:

@{
    Layout = "_Layout";
}

Předchozí revize nastaví soubor rozložení pro Pages/Shared/_Layout.cshtml všechny soubory ve složce PagesRazor. Další informace najdete v tématu Rozložení .

Model vytvořit stránku

Pages/Movies/Create.cshtml.cs Prozkoumejte model stránky:

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using RazorPagesMovie.Models;

namespace RazorPagesMovie.Pages.Movies
{
    public class CreateModel : PageModel
    {
        private readonly RazorPagesMovie.Data.RazorPagesMovieContext _context;

        public CreateModel(RazorPagesMovie.Data.RazorPagesMovieContext context)
        {
            _context = context;
        }

        public IActionResult OnGet()
        {
            return Page();
        }

        [BindProperty]
        public Movie Movie { get; set; } = default!;
        

        // To protect from overposting attacks, see https://aka.ms/RazorPagesCRUD
        public async Task<IActionResult> OnPostAsync()
        {
          if (!ModelState.IsValid || _context.Movie == null || Movie == null)
            {
                return Page();
            }

            _context.Movie.Add(Movie);
            await _context.SaveChangesAsync();

            return RedirectToPage("./Index");
        }
    }
}

Metoda OnGet inicializuje jakýkoli stav potřebný pro stránku. Stránka Vytvořit nemá k inicializaci žádný stav, takže Page se vrátí. V pozdější části kurzu se zobrazí příklad OnGet inicializace stavu. Metoda Page vytvoří PageResult objekt, který vykreslí Create.cshtml stránku.

Vlastnost Movie používá atribut [BindProperty] k vyjádření souhlasu s vazbou modelu. Při vytvoření formuláře publikuje hodnoty formuláře, ASP.NET Core runtime vytvoří vazbu odeslaných hodnot k Movie modelu.

Metoda OnPostAsync se spustí, když stránka publikuje data formuláře:

public async Task<IActionResult> OnPostAsync()
{
  if (!ModelState.IsValid || _context.Movie == null || Movie == null)
    {
        return Page();
    }

    _context.Movie.Add(Movie);
    await _context.SaveChangesAsync();

    return RedirectToPage("./Index");
}

Pokud dojde k nějakým chybám modelu, formulář se znovu zobrazí spolu s publikovanými daty formuláře. Většinu chyb modelu lze zachytit na straně klienta před odesláním formuláře. Příkladem chyby modelu je zaúčtování hodnoty pro pole kalendářního data, které nelze převést na datum. Ověření na straně klienta a ověření modelu se probírá později v tomto kurzu.

Pokud neexistují žádné chyby modelu:

  • Data se uloží.
  • Prohlížeč se přesměruje na stránku Index.

Stránka Vytvořit Razor

Prozkoumání stránkového Pages/Movies/Create.cshtmlRazor souboru:

@page
@model RazorPagesMovie.Pages.Movies.CreateModel

@{
    ViewData["Title"] = "Create";
}

<h1>Create</h1>

<h4>Movie</h4>
<hr />
<div class="row">
    <div class="col-md-4">
        <form method="post">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <div class="form-group">
                <label asp-for="Movie.Title" class="control-label"></label>
                <input asp-for="Movie.Title" class="form-control" />
                <span asp-validation-for="Movie.Title" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Movie.ReleaseDate" class="control-label"></label>
                <input asp-for="Movie.ReleaseDate" class="form-control" />
                <span asp-validation-for="Movie.ReleaseDate" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Movie.Genre" class="control-label"></label>
                <input asp-for="Movie.Genre" class="form-control" />
                <span asp-validation-for="Movie.Genre" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Movie.Price" class="control-label"></label>
                <input asp-for="Movie.Price" class="form-control" />
                <span asp-validation-for="Movie.Price" class="text-danger"></span>
            </div>
            <div class="form-group">
                <input type="submit" value="Create" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>

<div>
    <a asp-page="Index">Back to List</a>
</div>

@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}

Visual Studio zobrazí následující značky v odlišném tučném písmu použitém pro pomocné rutiny značek:

  • <form method="post">
  • <div asp-validation-summary="ModelOnly" class="text-danger"></div>
  • <label asp-for="Movie.Title" class="control-label"></label>
  • <input asp-for="Movie.Title" class="form-control" />
  • <span asp-validation-for="Movie.Title" class="text-danger"></span>

Zobrazení VS17 stránky Create.cshtml

Prvek <form method="post"> je pomocným rutinou značky formuláře. Pomocná rutina značky formuláře automaticky obsahuje antiforgery token.

Modul generování uživatelského rozhraní vytvoří Razor kód pro každé pole v modelu s výjimkou ID, podobně jako v následujícím příkladu:

<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
    <label asp-for="Movie.Title" class="control-label"></label>
    <input asp-for="Movie.Title" class="form-control" />
    <span asp-validation-for="Movie.Title" class="text-danger"></span>
</div>

Pomocné rutiny ověřovacích značek (<div asp-validation-summary a <span asp-validation-for) zobrazují chyby ověření. Ověřování je podrobněji popsáno dále v této sérii.

Pomocník značky popisku (<label asp-for="Movie.Title" class="control-label"></label>) vygeneruje popisek popis a [for] atribut pro Title vlastnost.

Pomocný rutina vstupní značky (<input asp-for="Movie.Title" class="form-control">) používá atributy DataAnnotations a vytváří atributy HTML potřebné pro ověřování jQuery na straně klienta.

Další informace o pomocných rutinách značek, jako <form method="post">je například , naleznete v tématu Pomocné rutiny značek v ASP.NET Core.

Další kroky

Stránky Vytvořit, Odstranit, Podrobnosti a Upravit

Pages/Movies/Index.cshtml.cs Prozkoumejte model stránky:

// Unused usings removed.
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using RazorPagesMovie.Models;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace RazorPagesMovie.Pages.Movies
{
    public class IndexModel : PageModel
    {
        private readonly RazorPagesMovie.Data.RazorPagesMovieContext _context;

        public IndexModel(RazorPagesMovie.Data.RazorPagesMovieContext context)
        {
            _context = context;
        }
        public IList<Movie> Movie { get;set; }

        public async Task OnGetAsync()
        {
            Movie = await _context.Movie.ToListAsync();
        }
    }
}

Razor Stránky jsou odvozeny z PageModel. Podle konvence PageModelje odvozená třída pojmenována <PageName>Model. Konstruktor pomocí injektáže závislostí přidá RazorPagesMovieContext na stránku:

public class IndexModel : PageModel
{
    private readonly RazorPagesMovie.Data.RazorPagesMovieContext _context;

    public IndexModel(RazorPagesMovie.Data.RazorPagesMovieContext context)
    {
        _context = context;
    }

Další informace o asynchronním programování pomocí Entity Frameworku najdete v asynchronním kódu .

Při požadavku na stránku OnGetAsync vrátí metoda seznam filmů na Razor stránku. Razor Na stránce OnGetAsync nebo OnGet je volána k inicializaci stavu stránky. V tomto případě OnGetAsync získá seznam filmů a zobrazí je.

Pokud OnGet se vrátí void nebo OnGetAsync vrátí Task, nepoužije se žádný návratový příkaz. Příklad stránky Privacy :

public class PrivacyModel : PageModel
{
    private readonly ILogger<PrivacyModel> _logger;

    public PrivacyModel(ILogger<PrivacyModel> logger)
    {
        _logger = logger;
    }

    public void OnGet()
    {
    }
}

Pokud je IActionResult návratový typ nebo Task<IActionResult>, musí být zadán návratový příkaz. Například Pages/Movies/Create.cshtml.csOnPostAsync metoda:

    public async Task<IActionResult> OnPostAsync()
    {
        if (!ModelState.IsValid)
        {
            return Page();
        }

        _context.Movie.Add(Movie);
        await _context.SaveChangesAsync();

        return RedirectToPage("./Index");
    }
}

Pages/Movies/Index.cshtmlRazor Prozkoumejte stránku:

@page
@model RazorPagesMovie.Pages.Movies.IndexModel

@{
    ViewData["Title"] = "Index";
}

<h1>Index</h1>

<p>
    <a asp-page="Create">Create New</a>
</p>
<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].Title)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].ReleaseDate)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].Genre)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].Price)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
@foreach (var item in Model.Movie) {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.Title)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.ReleaseDate)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Genre)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Price)
            </td>
            <td>
                <a asp-page="./Edit" asp-route-id="@item.ID">Edit</a> |
                <a asp-page="./Details" asp-route-id="@item.ID">Details</a> |
                <a asp-page="./Delete" asp-route-id="@item.ID">Delete</a>
            </td>
        </tr>
}
    </tbody>
</table>

Razor může přejít z HTML do jazyka C# nebo do Razorkódu specifického pro konkrétní značky. @ Když za symbolem následuje Razor vyhrazené klíčové slovo, přejde do Razorkódu specifického pro konkrétní kód, jinak přejde do jazyka C#.

Direktiva @page

Direktiva @pageRazor vytvoří soubor akci MVC, což znamená, že může zpracovávat požadavky. Direktiva @page musí být první direktivou Razor na stránce. @page a @model představují příklady přechodu na Razorkonkrétní značky. Další informace najdete Razor v syntaxi .

Direktiva @model

@page
@model RazorPagesMovie.Pages.Movies.IndexModel

Direktiva @model určuje typ modelu předaného stránce Razor . V předchozím příkladu @model řádek zpřístupňuje PageModeltřídu -odvozenou pro Razor stránku. Model se používá v pomocných rutinách @Html.DisplayNameFor@Html.DisplayFor HTML na stránce.

Prozkoumejte výraz lambda použitý v následujícím pomocníkovi HTML:

@Html.DisplayNameFor(model => model.Movie[0].Title)

Pomocník DisplayNameFor HTML zkontroluje Title vlastnost odkazovanou ve výrazu lambda a určí zobrazovaný název. Výraz lambda se kontroluje místo vyhodnocení. To znamená, že neexistuje žádné narušení přístupu, pokud model, model.Movienebo je nebo model.Movie[0] je null prázdné. Při vyhodnocování výrazu lambda, například pomocí @Html.DisplayFor(modelItem => item.Title), hodnoty vlastností modelu jsou vyhodnoceny.

Stránka rozložení

Vyberte nabídku odkazy RazorPagesMovie, Homea Privacy. Každá stránka zobrazuje stejné rozložení nabídky. V souboru se implementuje Pages/Shared/_Layout.cshtml rozložení nabídky.

Otevřete a prozkoumejte Pages/Shared/_Layout.cshtml soubor.

Šablony rozložení umožňují, aby rozložení kontejneru HTML bylo:

  • Zadané na jednom místě.
  • Používá se na více stránkách na webu.

@RenderBody() Najděte řádek. RenderBody je zástupný symbol, kde se všechna zobrazení specifická pro stránky zobrazují, zabalená na stránce rozložení. Vyberte například Privacy odkaz a Pages/Privacy.cshtml zobrazení se vykreslí RenderBody uvnitř metody.

ViewData a rozložení

Vezměte v úvahu Pages/Movies/Index.cshtml následující kód ze souboru:

@page
@model RazorPagesMovie.Pages.Movies.IndexModel

@{
    ViewData["Title"] = "Index";
}

Předchozí zvýrazněný kód je příkladem Razor přechodu na C#. } A { znaky ohraničují blok kódu jazyka C#.

Základní PageModel třída obsahuje vlastnost slovníku ViewData , která lze použít k předávání dat do zobrazení. Objekty se přidají do slovníku ViewDatapomocí vzoru klíč-hodnota. V předchozí ukázce se Title vlastnost přidá do slovníku ViewData .

Vlastnost Title se používá v Pages/Shared/_Layout.cshtml souboru. Následující kód ukazuje několik prvních řádků _Layout.cshtml souboru.

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - RazorPagesMovie</title>

    @*Markup removed for brevity.*@

Řádek @*Markup removed for brevity.*@ je Razor komentář. Na rozdíl od komentářů <!-- -->Razor HTML se komentáře do klienta neodesílají. Další informace najdete ve webové dokumentaci k MDN: Začínáme s HTML .

Aktualizace rozložení

  1. <title> Změňte prvek v Pages/Shared/_Layout.cshtml souboru tak, aby se místo RazorPagesMovie zobrazoval film.

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>@ViewData["Title"] - Movie</title>
    
  2. V souboru vyhledejte následující prvek ukotvení Pages/Shared/_Layout.cshtml .

    <a class="navbar-brand" asp-area="" asp-page="/Index">RazorPagesMovie</a>
    
  3. Nahraďte předchozí prvek následujícím kódem:

    <a class="navbar-brand" asp-page="/Movies/Index">RpMovie</a>
    

    Předchozí prvek ukotvení je pomocník značky. V tomto případě se jedná o pomocnou rutinu značky ukotvení. Atribut asp-page="/Movies/Index" Pomocné rutiny značky a hodnota vytvoří odkaz na /Movies/IndexRazor stránku. Hodnota asp-area atributu je prázdná, takže se tato oblast v odkazu nepoužívá. Další informace najdete v části Oblasti .

  4. Uložte změny a otestujte aplikaci výběrem odkazu RpMovie . Pokud máte nějaké problémy, podívejte se na soubor _Layout.cshtml na GitHubu.

  5. Otestujte odkazy Home, RpMovie, Vytvořit, Upravit a Odstranit . Každá stránka nastaví název, který můžete vidět na kartě prohlížeče. Při vytvoření záložky stránky se název použije pro záložku.

Poznámka:

Do pole pravděpodobně nebudete moct zadávat desetinné čárky Price . Pokud chcete podporovat ověřování jQuery pro neanglické národní prostředí používající čárku (",") pro desetinnou čárku a jiné formáty kalendářních dat než v angličtině, musíte provést kroky ke globalizaci aplikace. Pokyny k přidání desetinných čárk najdete v tomto problému Na GitHubu 4076 .

Vlastnost Layout je nastavena Pages/_ViewStart.cshtml v souboru:

@{
    Layout = "_Layout";
}

Předchozí revize nastaví soubor rozložení pro Pages/Shared/_Layout.cshtml všechny soubory ve složce PagesRazor. Další informace najdete v tématu Rozložení .

Model vytvořit stránku

Pages/Movies/Create.cshtml.cs Prozkoumejte model stránky:

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using RazorPagesMovie.Models;
using System;
using System.Threading.Tasks;

namespace RazorPagesMovie.Pages.Movies
{
    public class CreateModel : PageModel
    {
        private readonly RazorPagesMovie.Data.RazorPagesMovieContext _context;

        public CreateModel(RazorPagesMovie.Data.RazorPagesMovieContext context)
        {
            _context = context;
        }

        public IActionResult OnGet()
        {
            return Page();
        }

        [BindProperty]
        public Movie Movie { get; set; }

        public async Task<IActionResult> OnPostAsync()
        {
            if (!ModelState.IsValid)
            {
                return Page();
            }

            _context.Movie.Add(Movie);
            await _context.SaveChangesAsync();

            return RedirectToPage("./Index");
        }
    }
}

Metoda OnGet inicializuje jakýkoli stav potřebný pro stránku. Stránka Vytvořit nemá k inicializaci žádný stav, takže Page se vrátí. V pozdější části kurzu se zobrazí příklad OnGet inicializace stavu. Metoda Page vytvoří PageResult objekt, který vykreslí Create.cshtml stránku.

Vlastnost Movie používá atribut [BindProperty] k vyjádření souhlasu s vazbou modelu. Při vytvoření formuláře publikuje hodnoty formuláře, ASP.NET Core runtime vytvoří vazbu odeslaných hodnot k Movie modelu.

Metoda OnPostAsync se spustí, když stránka publikuje data formuláře:

public async Task<IActionResult> OnPostAsync()
{
    if (!ModelState.IsValid)
    {
        return Page();
    }

    _context.Movie.Add(Movie);
    await _context.SaveChangesAsync();

    return RedirectToPage("./Index");
}

Pokud dojde k nějakým chybám modelu, formulář se znovu zobrazí spolu s publikovanými daty formuláře. Většinu chyb modelu lze zachytit na straně klienta před odesláním formuláře. Příkladem chyby modelu je zaúčtování hodnoty pro pole kalendářního data, které nelze převést na datum. Ověření na straně klienta a ověření modelu se probírá později v tomto kurzu.

Pokud neexistují žádné chyby modelu:

  • Data se uloží.
  • Prohlížeč se přesměruje na stránku Index.

Stránka Vytvořit Razor

Prozkoumání stránkového Pages/Movies/Create.cshtmlRazor souboru:

@page
@model RazorPagesMovie.Pages.Movies.CreateModel

@{
    ViewData["Title"] = "Create";
}

<h1>Create</h1>

<h4>Movie</h4>
<hr />
<div class="row">
    <div class="col-md-4">
        <form method="post">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <div class="form-group">
                <label asp-for="Movie.Title" class="control-label"></label>
                <input asp-for="Movie.Title" class="form-control" />
                <span asp-validation-for="Movie.Title" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Movie.ReleaseDate" class="control-label"></label>
                <input asp-for="Movie.ReleaseDate" class="form-control" />
                <span asp-validation-for="Movie.ReleaseDate" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Movie.Genre" class="control-label"></label>
                <input asp-for="Movie.Genre" class="form-control" />
                <span asp-validation-for="Movie.Genre" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Movie.Price" class="control-label"></label>
                <input asp-for="Movie.Price" class="form-control" />
                <span asp-validation-for="Movie.Price" class="text-danger"></span>
            </div>
            <div class="form-group">
                <input type="submit" value="Create" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>

<div>
    <a asp-page="Index">Back to List</a>
</div>

@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}

Visual Studio zobrazí následující značky v odlišném tučném písmu použitém pro pomocné rutiny značek:

  • <form method="post">
  • <div asp-validation-summary="ModelOnly" class="text-danger"></div>
  • <label asp-for="Movie.Title" class="control-label"></label>
  • <input asp-for="Movie.Title" class="form-control" />
  • <span asp-validation-for="Movie.Title" class="text-danger"></span>

Zobrazení VS17 stránky Create.cshtml

Prvek <form method="post"> je pomocným rutinou značky formuláře. Pomocná rutina značky formuláře automaticky obsahuje antiforgery token.

Modul generování uživatelského rozhraní vytvoří Razor kód pro každé pole v modelu s výjimkou ID, podobně jako v následujícím příkladu:

<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
    <label asp-for="Movie.Title" class="control-label"></label>
    <input asp-for="Movie.Title" class="form-control" />
    <span asp-validation-for="Movie.Title" class="text-danger"></span>
</div>

Pomocné rutiny ověřovacích značek (<div asp-validation-summary a <span asp-validation-for) zobrazují chyby ověření. Ověřování je podrobněji popsáno dále v této sérii.

Pomocník značky popisku (<label asp-for="Movie.Title" class="control-label"></label>) vygeneruje popisek popis a [for] atribut pro Title vlastnost.

Pomocný rutina vstupní značky (<input asp-for="Movie.Title" class="form-control">) používá atributy DataAnnotations a vytváří atributy HTML potřebné pro ověřování jQuery na straně klienta.

Další informace o pomocných rutinách značek, jako <form method="post">je například , naleznete v tématu Pomocné rutiny značek v ASP.NET Core.

Další kroky