Část 6, metody kontroleru a zobrazení 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

Máme dobrý začátek filmové aplikace, ale prezentace není ideální, například ReleaseDate by měla být dvě slova.

Zobrazení indexu: Datum vydání je jedno slovo (bez mezery) a každé datum vydání filmu ukazuje čas 12:00

Models/Movie.cs Otevřete soubor a přidejte zvýrazněné řádky uvedené níže:

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace MvcMovie.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; }
}

DataAnnotations jsou vysvětleny v dalším kurzu. Atribut Display určuje, co se má zobrazit pro název pole (v tomto případě "Datum vydání" místo "ReleaseDate"). Atribut DataType určuje typ dat (Date), takže se nezobrazují informace o čase uloženém v poli.

Je vyžadována [Column(TypeName = "decimal(18, 2)")] datová poznámka, aby entity Framework Core bylo možné správně namapovat Price na měnu v databázi. Další informace naleznete v tématu Datové typy.

Přejděte na Movies kontroler a podržte ukazatel myši nad odkazem Pro úpravy a zobrazte cílovou adresu URL.

Okno prohlížeče s myší na odkaz Upravit a zobrazená adresa URL https://localhost:5001/Movies/Edit/5 odkazu

Odkazy Upravit, Podrobnosti a Odstranit jsou generovány pomocným rutinou základní značky ukotvení MVC v Views/Movies/Index.cshtml souboru.

        <a asp-action="Edit" asp-route-id="@item.Id">Edit</a> |
        <a asp-action="Details" asp-route-id="@item.Id">Details</a> |
        <a asp-action="Delete" asp-route-id="@item.Id">Delete</a>
    </td>
</tr>

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. Ve výše uvedeném AnchorTagHelper kódu dynamicky generuje hodnotu atributu HTML href z metody akce kontroleru a ID trasy. Ke zkoumání vygenerovaných značek použijete zobrazení zdroje z oblíbeného prohlížeče nebo použijete vývojářské nástroje. Část vygenerovaného kódu HTML je znázorněná níže:

 <td>
    <a href="/Movies/Edit/4"> Edit </a> |
    <a href="/Movies/Details/4"> Details </a> |
    <a href="/Movies/Delete/4"> Delete </a>
</td>

Vzpomeňte si formát pro směrování nastavený v Program.cs souboru:

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

ASP.NET Core se přeloží https://localhost:5001/Movies/Edit/4 na požadavek na metodu EditMovies akce kontroleru s parametrem Id 4. (Metody kontroleru se označují také jako metody akcí.)

Pomocné rutiny značek jsou jednou z nejoblíbenějších nových funkcí ASP.NET Core. Další informace najdete v tématu Další zdroje informací.

Movies Otevřete kontroler a prozkoumejte dvě Edit metody akcí. Následující kód ukazuje metodu HTTP GET Edit , která načte film a naplní formulář pro úpravy vygenerovaný souborem Edit.cshtmlRazor .

// GET: Movies/Edit/5
public async Task<IActionResult> Edit(int? id)
{
    if (id == null)
    {
        return NotFound();
    }

    var movie = await _context.Movie.FindAsync(id);
    if (movie == null)
    {
        return NotFound();
    }
    return View(movie);
}

Následující kód ukazuje metodu HTTP POST Edit , která zpracovává publikované hodnoty filmu:

// POST: Movies/Edit/5
// To protect from overposting attacks, enable the specific properties you want to bind to.
// For more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("Id,Title,ReleaseDate,Genre,Price,Rating")] Movie movie)
{
    if (id != movie.Id)
    {
        return NotFound();
    }

    if (ModelState.IsValid)
    {
        try
        {
            _context.Update(movie);
            await _context.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException)
        {
            if (!MovieExists(movie.Id))
            {
                return NotFound();
            }
            else
            {
                throw;
            }
        }
        return RedirectToAction(nameof(Index));
    }
    return View(movie);
}

Atribut [Bind] je jedním ze způsobů, jak chránit před nadměrným účtováním. Do atributu [Bind] , který chcete změnit, byste měli zahrnout pouze vlastnosti. Další informace naleznete v tématu Ochrana kontroleru před nadměrným publikováním. Modely ViewModel představují alternativní přístup, který zabrání nadměrnému účtování.

Všimněte si, že před atributem [HttpPost] předchází druhá Edit metoda akce.

// POST: Movies/Edit/5
// To protect from overposting attacks, enable the specific properties you want to bind to.
// For more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("Id,Title,ReleaseDate,Genre,Price,Rating")] Movie movie)
{
    if (id != movie.Id)
    {
        return NotFound();
    }

    if (ModelState.IsValid)
    {
        try
        {
            _context.Update(movie);
            await _context.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException)
        {
            if (!MovieExists(movie.Id))
            {
                return NotFound();
            }
            else
            {
                throw;
            }
        }
        return RedirectToAction(nameof(Index));
    }
    return View(movie);
}

Atribut HttpPost určuje, že tuto Edit metodu lze vyvolat pouze pro POST požadavky. Atribut můžete použít [HttpGet] u první metody úprav, ale to není nutné, protože [HttpGet] je to výchozí.

Atribut ValidateAntiForgeryToken se používá k zabránění padělání požadavku a je spárován s tokenem proti padělání vygenerovaném v souboru zobrazení pro úpravy (Views/Movies/Edit.cshtml). Soubor zobrazení pro úpravy vygeneruje token proti padělání pomocí pomocné rutiny značky formuláře.

<form asp-action="Edit">

Pomocník značky formuláře vygeneruje skrytý token proti padělání, který se musí shodovat s [ValidateAntiForgeryToken] vygenerovaným anti-forgery token v Edit metodě kontroleru Movies. Další informace najdete v tématu Prevence útoků založených na padělání žádosti posílané mezi weby (XSRF/CSRF) v ASP.NET Core.

Metoda HttpGet Edit vezme parametr filmu ID , vyhledá film pomocí metody Entity Framework FindAsync a vrátí vybraný film do zobrazení Pro úpravy. Pokud se video nenašlo, NotFound vrátí se (HTTP 404).

// GET: Movies/Edit/5
public async Task<IActionResult> Edit(int? id)
{
    if (id == null)
    {
        return NotFound();
    }

    var movie = await _context.Movie.FindAsync(id);
    if (movie == null)
    {
        return NotFound();
    }
    return View(movie);
}

Když systém generování uživatelského rozhraní vytvořil zobrazení Edit, prozkoumal Movie třídu a vytvořil kód pro vykreslení <label> a <input> prvky pro každou vlastnost třídy. Následující příklad ukazuje zobrazení pro úpravy vygenerované systémem generování uživatelského rozhraní sady Visual Studio:

@model MvcMovie.Models.Movie

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

<h1>Edit</h1>

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

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

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

Všimněte si, že šablona zobrazení obsahuje @model MvcMovie.Models.Movie příkaz v horní části souboru. @model MvcMovie.Models.Movie určuje, že zobrazení očekává model šablony zobrazení typu Movie.

Vygenerovaný kód používá několik pomocných metod značek ke zjednodušení kódu HTML. Pomocník značky popisku zobrazí název pole (Název, ReleaseDate, Žánr nebo Cena). Pomocné rutiny vstupní značky vykresluje element HTML<input>. Pomocník ověřovací značky zobrazí všechny ověřovací zprávy přidružené k této vlastnosti.

Spusťte aplikaci a přejděte na /Movies adresu URL. Klikněte na odkaz Upravit. V prohlížeči zobrazte zdroj stránky. Vygenerovaný kód HTML pro <form> element je zobrazen níže.

<form action="/Movies/Edit/7" method="post">
    <div class="form-horizontal">
        <h4>Movie</h4>
        <hr />
        <div class="text-danger" />
        <input type="hidden" data-val="true" data-val-required="The ID field is required." id="ID" name="ID" value="7" />
        <div class="form-group">
            <label class="control-label col-md-2" for="Genre" />
            <div class="col-md-10">
                <input class="form-control" type="text" id="Genre" name="Genre" value="Western" />
                <span class="text-danger field-validation-valid" data-valmsg-for="Genre" data-valmsg-replace="true"></span>
            </div>
        </div>
        <div class="form-group">
            <label class="control-label col-md-2" for="Price" />
            <div class="col-md-10">
                <input class="form-control" type="text" data-val="true" data-val-number="The field Price must be a number." data-val-required="The Price field is required." id="Price" name="Price" value="3.99" />
                <span class="text-danger field-validation-valid" data-valmsg-for="Price" data-valmsg-replace="true"></span>
            </div>
        </div>
        <!-- Markup removed for brevity -->
        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Save" class="btn btn-default" />
            </div>
        </div>
    </div>
    <input name="__RequestVerificationToken" type="hidden" value="CfDJ8Inyxgp63fRFqUePGvuI5jGZsloJu1L7X9le1gy7NCIlSduCRx9jDQClrV9pOTTmqUyXnJBXhmrjcUVDJyDUMm7-MF_9rK8aAZdRdlOri7FmKVkRe_2v5LIHGKFcTjPrWPYnc9AdSbomkiOSaTEg7RU" />
</form>

Prvky <input> jsou v elementu HTML <form> , jehož action atribut je nastaven na publikování na /Movies/Edit/id adresu URL. Data formuláře se publikují na server po kliknutí na Save tlačítko. Poslední řádek před uzavíracím </form> prvkem zobrazuje skrytý token XSRF vygenerovaný pomocným pomocníkem značky formuláře.

Zpracování požadavku POST

Následující výpis ukazuje [HttpPost] verzi Edit metody akce.

// POST: Movies/Edit/5
// To protect from overposting attacks, enable the specific properties you want to bind to.
// For more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("Id,Title,ReleaseDate,Genre,Price,Rating")] Movie movie)
{
    if (id != movie.Id)
    {
        return NotFound();
    }

    if (ModelState.IsValid)
    {
        try
        {
            _context.Update(movie);
            await _context.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException)
        {
            if (!MovieExists(movie.Id))
            {
                return NotFound();
            }
            else
            {
                throw;
            }
        }
        return RedirectToAction(nameof(Index));
    }
    return View(movie);
}

Atribut [ValidateAntiForgeryToken] ověří skrytý token XSRF vygenerovaný generátorem tokenů proti padělání v pomocné rutině značky formuláře.

Systém vazby modelu přebírá publikované hodnoty formuláře a vytvoří Movie objekt, který se předává jako movie parametr. Vlastnost ModelState.IsValid ověřuje, že data odeslaná ve formuláři lze použít k úpravě (úpravě nebo aktualizaci) objektu Movie . Pokud jsou data platná, uloží se. Aktualizovaná (upravená) data videa se ukládají do databáze voláním SaveChangesAsync metody kontextu databáze. Po uložení dat kód přesměruje uživatele na Index metodu MoviesController akce třídy, která zobrazí kolekci filmů včetně právě provedených změn.

Než se formulář odešle na server, ověření na straně klienta zkontroluje všechna ověřovací pravidla v polích. Pokud dojde k nějakým chybám ověření, zobrazí se chybová zpráva a formulář se neúčtuje. Pokud je JavaScript zakázaný, nebudete mít ověření na straně klienta, ale server rozpozná publikované hodnoty, které nejsou platné, a hodnoty formuláře se znovu zobrazí s chybovými zprávami. Později v tomto kurzu podrobněji prozkoumáme ověření modelu. Pomocná rutina ověřovací značky v Views/Movies/Edit.cshtml šabloně zobrazení se postará o zobrazení odpovídajících chybových zpráv.

Zobrazení pro úpravy: Výjimka pro nesprávnou hodnotu Cena abc uvádí, že pole Cena musí být číslo. Výjimka pro nesprávnou hodnotu data vydání xyz stavů Zadejte platné datum.

HttpGet Všechny metody v řadiči videa se řídí podobným vzorem. Načte objekt videa (nebo seznam objektů v případě Index) a předají objekt (model) do zobrazení. Metoda Create předá do zobrazení prázdný objekt Create videa. Všechny metody, které vytvářejí, upravují, odstraňují nebo jinak upravují data, to dělají v [HttpPost] přetížení metody. Úprava dat v metodě HTTP GET představuje bezpečnostní riziko. Úprava dat v HTTP GET metodě také porušuje osvědčené postupy HTTP a vzor architektury REST , který určuje, že požadavky GET by neměly měnit stav vaší aplikace. Jinými slovy, provedení operace GET by měla být bezpečná operace, která nemá žádné vedlejší účinky a neupravuje trvalá data.

Další materiály

Máme dobrý začátek filmové aplikace, ale prezentace není ideální, například ReleaseDate by měla být dvě slova.

Zobrazení indexu: Datum vydání je jedno slovo (bez mezery) a každé datum vydání filmu ukazuje čas 12:00

Models/Movie.cs Otevřete soubor a přidejte zvýrazněné řádky uvedené níže:

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace MvcMovie.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; }
}

DataAnnotations jsou vysvětleny v dalším kurzu. Atribut Display určuje, co se má zobrazit pro název pole (v tomto případě "Datum vydání" místo "ReleaseDate"). Atribut DataType určuje typ dat (Date), takže se nezobrazují informace o čase uloženém v poli.

Je vyžadována [Column(TypeName = "decimal(18, 2)")] datová poznámka, aby entity Framework Core bylo možné správně namapovat Price na měnu v databázi. Další informace naleznete v tématu Datové typy.

Přejděte na Movies kontroler a podržte ukazatel myši nad odkazem Pro úpravy a zobrazte cílovou adresu URL.

Okno prohlížeče s myší na odkaz Upravit a zobrazená adresa URL https://localhost:5001/Movies/Edit/5 odkazu

Odkazy Upravit, Podrobnosti a Odstranit jsou generovány pomocným rutinou základní značky ukotvení MVC v Views/Movies/Index.cshtml souboru.

        <a asp-action="Edit" asp-route-id="@item.Id">Edit</a> |
        <a asp-action="Details" asp-route-id="@item.Id">Details</a> |
        <a asp-action="Delete" asp-route-id="@item.Id">Delete</a>
    </td>
</tr>

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. Ve výše uvedeném AnchorTagHelper kódu dynamicky generuje hodnotu atributu HTML href z metody akce kontroleru a ID trasy. Ke zkoumání vygenerovaných značek použijete zobrazení zdroje z oblíbeného prohlížeče nebo použijete vývojářské nástroje. Část vygenerovaného kódu HTML je znázorněná níže:

 <td>
    <a href="/Movies/Edit/4"> Edit </a> |
    <a href="/Movies/Details/4"> Details </a> |
    <a href="/Movies/Delete/4"> Delete </a>
</td>

Vzpomeňte si formát pro směrování nastavený v Program.cs souboru:

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

ASP.NET Core se přeloží https://localhost:5001/Movies/Edit/4 na požadavek na metodu EditMovies akce kontroleru s parametrem Id 4. (Metody kontroleru se označují také jako metody akcí.)

Pomocné rutiny značek jsou jednou z nejoblíbenějších nových funkcí ASP.NET Core. Další informace najdete v tématu Další zdroje informací.

Movies Otevřete kontroler a prozkoumejte dvě Edit metody akcí. Následující kód ukazuje metodu HTTP GET Edit , která načte film a naplní formulář pro úpravy vygenerovaný souborem Edit.cshtmlRazor .

// GET: Movies/Edit/5
public async Task<IActionResult> Edit(int? id)
{
    if (id == null)
    {
        return NotFound();
    }

    var movie = await _context.Movie.FindAsync(id);
    if (movie == null)
    {
        return NotFound();
    }
    return View(movie);
}

Následující kód ukazuje metodu HTTP POST Edit , která zpracovává publikované hodnoty filmu:

// POST: Movies/Edit/5
// To protect from overposting attacks, enable the specific properties you want to bind to.
// For more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("Id,Title,ReleaseDate,Genre,Price,Rating")] Movie movie)
{
    if (id != movie.Id)
    {
        return NotFound();
    }

    if (ModelState.IsValid)
    {
        try
        {
            _context.Update(movie);
            await _context.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException)
        {
            if (!MovieExists(movie.Id))
            {
                return NotFound();
            }
            else
            {
                throw;
            }
        }
        return RedirectToAction(nameof(Index));
    }
    return View(movie);
}

Atribut [Bind] je jedním ze způsobů, jak chránit před nadměrným účtováním. Do atributu [Bind] , který chcete změnit, byste měli zahrnout pouze vlastnosti. Další informace naleznete v tématu Ochrana kontroleru před nadměrným publikováním. Modely ViewModel představují alternativní přístup, který zabrání nadměrnému účtování.

Všimněte si, že před atributem [HttpPost] předchází druhá Edit metoda akce.

// POST: Movies/Edit/5
// To protect from overposting attacks, enable the specific properties you want to bind to.
// For more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("Id,Title,ReleaseDate,Genre,Price,Rating")] Movie movie)
{
    if (id != movie.Id)
    {
        return NotFound();
    }

    if (ModelState.IsValid)
    {
        try
        {
            _context.Update(movie);
            await _context.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException)
        {
            if (!MovieExists(movie.Id))
            {
                return NotFound();
            }
            else
            {
                throw;
            }
        }
        return RedirectToAction(nameof(Index));
    }
    return View(movie);
}

Atribut HttpPost určuje, že tuto Edit metodu lze vyvolat pouze pro POST požadavky. Atribut můžete použít [HttpGet] u první metody úprav, ale to není nutné, protože [HttpGet] je to výchozí.

Atribut ValidateAntiForgeryToken se používá k zabránění padělání požadavku a je spárován s tokenem proti padělání vygenerovaném v souboru zobrazení pro úpravy (Views/Movies/Edit.cshtml). Soubor zobrazení pro úpravy vygeneruje token proti padělání pomocí pomocné rutiny značky formuláře.

<form asp-action="Edit">

Pomocník značky formuláře vygeneruje skrytý token proti padělání, který se musí shodovat s [ValidateAntiForgeryToken] vygenerovaným anti-forgery token v Edit metodě kontroleru Movies. Další informace najdete v tématu Prevence útoků založených na padělání žádosti posílané mezi weby (XSRF/CSRF) v ASP.NET Core.

Metoda HttpGet Edit vezme parametr filmu ID , vyhledá film pomocí metody Entity Framework FindAsync a vrátí vybraný film do zobrazení Pro úpravy. Pokud se video nenašlo, NotFound vrátí se (HTTP 404).

// GET: Movies/Edit/5
public async Task<IActionResult> Edit(int? id)
{
    if (id == null)
    {
        return NotFound();
    }

    var movie = await _context.Movie.FindAsync(id);
    if (movie == null)
    {
        return NotFound();
    }
    return View(movie);
}

Když systém generování uživatelského rozhraní vytvořil zobrazení Edit, prozkoumal Movie třídu a vytvořil kód pro vykreslení <label> a <input> prvky pro každou vlastnost třídy. Následující příklad ukazuje zobrazení pro úpravy vygenerované systémem generování uživatelského rozhraní sady Visual Studio:

@model MvcMovie.Models.Movie

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

<h1>Edit</h1>

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

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

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

Všimněte si, že šablona zobrazení obsahuje @model MvcMovie.Models.Movie příkaz v horní části souboru. @model MvcMovie.Models.Movie určuje, že zobrazení očekává model šablony zobrazení typu Movie.

Vygenerovaný kód používá několik pomocných metod značek ke zjednodušení kódu HTML. Pomocník značky popisku zobrazí název pole (Název, ReleaseDate, Žánr nebo Cena). Pomocné rutiny vstupní značky vykresluje element HTML<input>. Pomocník ověřovací značky zobrazí všechny ověřovací zprávy přidružené k této vlastnosti.

Spusťte aplikaci a přejděte na /Movies adresu URL. Klikněte na odkaz Upravit. V prohlížeči zobrazte zdroj stránky. Vygenerovaný kód HTML pro <form> element je zobrazen níže.

<form action="/Movies/Edit/7" method="post">
    <div class="form-horizontal">
        <h4>Movie</h4>
        <hr />
        <div class="text-danger" />
        <input type="hidden" data-val="true" data-val-required="The ID field is required." id="ID" name="ID" value="7" />
        <div class="form-group">
            <label class="control-label col-md-2" for="Genre" />
            <div class="col-md-10">
                <input class="form-control" type="text" id="Genre" name="Genre" value="Western" />
                <span class="text-danger field-validation-valid" data-valmsg-for="Genre" data-valmsg-replace="true"></span>
            </div>
        </div>
        <div class="form-group">
            <label class="control-label col-md-2" for="Price" />
            <div class="col-md-10">
                <input class="form-control" type="text" data-val="true" data-val-number="The field Price must be a number." data-val-required="The Price field is required." id="Price" name="Price" value="3.99" />
                <span class="text-danger field-validation-valid" data-valmsg-for="Price" data-valmsg-replace="true"></span>
            </div>
        </div>
        <!-- Markup removed for brevity -->
        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Save" class="btn btn-default" />
            </div>
        </div>
    </div>
    <input name="__RequestVerificationToken" type="hidden" value="CfDJ8Inyxgp63fRFqUePGvuI5jGZsloJu1L7X9le1gy7NCIlSduCRx9jDQClrV9pOTTmqUyXnJBXhmrjcUVDJyDUMm7-MF_9rK8aAZdRdlOri7FmKVkRe_2v5LIHGKFcTjPrWPYnc9AdSbomkiOSaTEg7RU" />
</form>

Prvky <input> jsou v elementu HTML <form> , jehož action atribut je nastaven na publikování na /Movies/Edit/id adresu URL. Data formuláře se publikují na server po kliknutí na Save tlačítko. Poslední řádek před uzavíracím </form> prvkem zobrazuje skrytý token XSRF vygenerovaný pomocným pomocníkem značky formuláře.

Zpracování požadavku POST

Následující výpis ukazuje [HttpPost] verzi Edit metody akce.

// POST: Movies/Edit/5
// To protect from overposting attacks, enable the specific properties you want to bind to.
// For more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("Id,Title,ReleaseDate,Genre,Price,Rating")] Movie movie)
{
    if (id != movie.Id)
    {
        return NotFound();
    }

    if (ModelState.IsValid)
    {
        try
        {
            _context.Update(movie);
            await _context.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException)
        {
            if (!MovieExists(movie.Id))
            {
                return NotFound();
            }
            else
            {
                throw;
            }
        }
        return RedirectToAction(nameof(Index));
    }
    return View(movie);
}

Atribut [ValidateAntiForgeryToken] ověří skrytý token XSRF vygenerovaný generátorem tokenů proti padělání v pomocné rutině značky formuláře.

Systém vazby modelu přebírá publikované hodnoty formuláře a vytvoří Movie objekt, který se předává jako movie parametr. Vlastnost ModelState.IsValid ověřuje, že data odeslaná ve formuláři lze použít k úpravě (úpravě nebo aktualizaci) objektu Movie . Pokud jsou data platná, uloží se. Aktualizovaná (upravená) data videa se ukládají do databáze voláním SaveChangesAsync metody kontextu databáze. Po uložení dat kód přesměruje uživatele na Index metodu MoviesController akce třídy, která zobrazí kolekci filmů včetně právě provedených změn.

Než se formulář odešle na server, ověření na straně klienta zkontroluje všechna ověřovací pravidla v polích. Pokud dojde k nějakým chybám ověření, zobrazí se chybová zpráva a formulář se neúčtuje. Pokud je JavaScript zakázaný, nebudete mít ověření na straně klienta, ale server rozpozná publikované hodnoty, které nejsou platné, a hodnoty formuláře se znovu zobrazí s chybovými zprávami. Později v tomto kurzu podrobněji prozkoumáme ověření modelu. Pomocná rutina ověřovací značky v Views/Movies/Edit.cshtml šabloně zobrazení se postará o zobrazení odpovídajících chybových zpráv.

Zobrazení pro úpravy: Výjimka pro nesprávnou hodnotu Cena abc uvádí, že pole Cena musí být číslo. Výjimka pro nesprávnou hodnotu data vydání xyz stavů Zadejte platné datum.

HttpGet Všechny metody v řadiči videa se řídí podobným vzorem. Načte objekt videa (nebo seznam objektů v případě Index) a předají objekt (model) do zobrazení. Metoda Create předá do zobrazení prázdný objekt Create videa. Všechny metody, které vytvářejí, upravují, odstraňují nebo jinak upravují data, to dělají v [HttpPost] přetížení metody. Úprava dat v metodě HTTP GET představuje bezpečnostní riziko. Úprava dat v HTTP GET metodě také porušuje osvědčené postupy HTTP a vzor architektury REST , který určuje, že požadavky GET by neměly měnit stav vaší aplikace. Jinými slovy, provedení operace GET by měla být bezpečná operace, která nemá žádné vedlejší účinky a neupravuje trvalá data.

Další materiály

Máme dobrý začátek filmové aplikace, ale prezentace není ideální, například ReleaseDate by měla být dvě slova.

Zobrazení indexu: Datum vydání je jedno slovo (bez mezery) a každé datum vydání filmu ukazuje čas 12:00

Models/Movie.cs Otevřete soubor a přidejte zvýrazněné řádky uvedené níže:

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace MvcMovie.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; }
    }
}

DataAnnotations jsou vysvětleny v dalším kurzu. Atribut Display určuje, co se má zobrazit pro název pole (v tomto případě "Datum vydání" místo "ReleaseDate"). Atribut DataType určuje typ dat (Date), takže se nezobrazují informace o čase uloženém v poli.

Je vyžadována [Column(TypeName = "decimal(18, 2)")] datová poznámka, aby entity Framework Core bylo možné správně namapovat Price na měnu v databázi. Další informace naleznete v tématu Datové typy.

Přejděte na Movies kontroler a podržte ukazatel myši nad odkazem Pro úpravy a zobrazte cílovou adresu URL.

Okno prohlížeče s myší na odkaz Upravit a zobrazená adresa URL https://localhost:5001/Movies/Edit/5 odkazu

Odkazy Upravit, Podrobnosti a Odstranit jsou generovány pomocným rutinou základní značky ukotvení MVC v Views/Movies/Index.cshtml souboru.

        <a asp-action="Edit" asp-route-id="@item.Id">Edit</a> |
        <a asp-action="Details" asp-route-id="@item.Id">Details</a> |
        <a asp-action="Delete" asp-route-id="@item.Id">Delete</a>
    </td>
</tr>

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. Ve výše uvedeném AnchorTagHelper kódu dynamicky generuje hodnotu atributu HTML href z metody akce kontroleru a ID trasy. Ke zkoumání vygenerovaných značek použijete zobrazení zdroje z oblíbeného prohlížeče nebo použijete vývojářské nástroje. Část vygenerovaného kódu HTML je znázorněná níže:

 <td>
    <a href="/Movies/Edit/4"> Edit </a> |
    <a href="/Movies/Details/4"> Details </a> |
    <a href="/Movies/Delete/4"> Delete </a>
</td>

Vzpomeňte si formát pro směrování nastavený v Program.cs souboru:

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

ASP.NET Core se přeloží https://localhost:5001/Movies/Edit/4 na požadavek na metodu EditMovies akce kontroleru s parametrem Id 4. (Metody kontroleru se označují také jako metody akcí.)

Pomocné rutiny značek jsou oblíbenou funkcí ASP.NET Core. Další informace o nich najdete v tématu Další zdroje informací.

Movies Otevřete kontroler a prozkoumejte dvě Edit metody akcí. Následující kód ukazuje metodu HTTP GET Edit , která načte film a naplní formulář pro úpravy vygenerovaný souborem Edit.cshtmlRazor .

// GET: Movies/Edit/5
public async Task<IActionResult> Edit(int? id)
{
    if (id == null)
    {
        return NotFound();
    }

    var movie = await _context.Movie.FindAsync(id);
    if (movie == null)
    {
        return NotFound();
    }
    return View(movie);
}

Následující kód ukazuje metodu HTTP POST Edit , která zpracovává publikované hodnoty filmu:

// POST: Movies/Edit/5
// To protect from overposting attacks, enable the specific properties you want to bind to.
// For more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("Id,Title,ReleaseDate,Genre,Price,Rating")] Movie movie)
{
    if (id != movie.Id)
    {
        return NotFound();
    }

    if (ModelState.IsValid)
    {
        try
        {
            _context.Update(movie);
            await _context.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException)
        {
            if (!MovieExists(movie.Id))
            {
                return NotFound();
            }
            else
            {
                throw;
            }
        }
        return RedirectToAction(nameof(Index));
    }
    return View(movie);
}

Atribut [Bind] je jedním ze způsobů, jak chránit před nadměrným účtováním. Do atributu [Bind] , který chcete změnit, byste měli zahrnout pouze vlastnosti. Další informace naleznete v tématu Ochrana kontroleru před nadměrným publikováním. Modely ViewModel představují alternativní přístup, který zabrání nadměrnému účtování.

Všimněte si, že před atributem [HttpPost] předchází druhá Edit metoda akce.

// POST: Movies/Edit/5
// To protect from overposting attacks, enable the specific properties you want to bind to.
// For more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("Id,Title,ReleaseDate,Genre,Price,Rating")] Movie movie)
{
    if (id != movie.Id)
    {
        return NotFound();
    }

    if (ModelState.IsValid)
    {
        try
        {
            _context.Update(movie);
            await _context.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException)
        {
            if (!MovieExists(movie.Id))
            {
                return NotFound();
            }
            else
            {
                throw;
            }
        }
        return RedirectToAction(nameof(Index));
    }
    return View(movie);
}

Atribut HttpPost určuje, že tuto Edit metodu lze vyvolat pouze pro POST požadavky. Atribut můžete použít [HttpGet] u první metody úprav, ale to není nutné, protože [HttpGet] je to výchozí.

Atribut ValidateAntiForgeryToken se používá k zabránění padělání požadavku a je spárován s tokenem proti padělání vygenerovaném v souboru zobrazení pro úpravy (Views/Movies/Edit.cshtml). Soubor zobrazení pro úpravy vygeneruje token proti padělání pomocí pomocné rutiny značky formuláře.

<form asp-action="Edit">

Pomocník značky formuláře vygeneruje skrytý token proti padělání, který se musí shodovat s [ValidateAntiForgeryToken] vygenerovaným anti-forgery token v Edit metodě kontroleru Movies. Další informace najdete v tématu Prevence útoků založených na padělání žádosti posílané mezi weby (XSRF/CSRF) v ASP.NET Core.

Metoda HttpGet Edit vezme parametr filmu ID , vyhledá film pomocí metody Entity Framework FindAsync a vrátí vybraný film do zobrazení Pro úpravy. Pokud se video nenašlo, NotFound vrátí se (HTTP 404).

// GET: Movies/Edit/5
public async Task<IActionResult> Edit(int? id)
{
    if (id == null)
    {
        return NotFound();
    }

    var movie = await _context.Movie.FindAsync(id);
    if (movie == null)
    {
        return NotFound();
    }
    return View(movie);
}

Když systém generování uživatelského rozhraní vytvořil zobrazení Edit, prozkoumal Movie třídu a vytvořil kód pro vykreslení <label> a <input> prvky pro každou vlastnost třídy. Následující příklad ukazuje zobrazení pro úpravy vygenerované systémem generování uživatelského rozhraní sady Visual Studio:

@model MvcMovie.Models.Movie

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

<h1>Edit</h1>

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

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

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

Všimněte si, že šablona zobrazení obsahuje @model MvcMovie.Models.Movie příkaz v horní části souboru. @model MvcMovie.Models.Movie určuje, že zobrazení očekává model šablony zobrazení typu Movie.

Vygenerovaný kód používá několik pomocných metod značek ke zjednodušení kódu HTML. Pomocník značky popisku zobrazí název pole (Název, ReleaseDate, Žánr nebo Cena). Pomocné rutiny vstupní značky vykresluje element HTML<input>. Pomocník ověřovací značky zobrazí všechny ověřovací zprávy přidružené k této vlastnosti.

Spusťte aplikaci a přejděte na /Movies adresu URL. Klikněte na odkaz Upravit. V prohlížeči zobrazte zdroj stránky. Vygenerovaný kód HTML pro <form> element je zobrazen níže.

<form action="/Movies/Edit/7" method="post">
    <div class="form-horizontal">
        <h4>Movie</h4>
        <hr />
        <div class="text-danger" />
        <input type="hidden" data-val="true" data-val-required="The ID field is required." id="ID" name="ID" value="7" />
        <div class="form-group">
            <label class="control-label col-md-2" for="Genre" />
            <div class="col-md-10">
                <input class="form-control" type="text" id="Genre" name="Genre" value="Western" />
                <span class="text-danger field-validation-valid" data-valmsg-for="Genre" data-valmsg-replace="true"></span>
            </div>
        </div>
        <div class="form-group">
            <label class="control-label col-md-2" for="Price" />
            <div class="col-md-10">
                <input class="form-control" type="text" data-val="true" data-val-number="The field Price must be a number." data-val-required="The Price field is required." id="Price" name="Price" value="3.99" />
                <span class="text-danger field-validation-valid" data-valmsg-for="Price" data-valmsg-replace="true"></span>
            </div>
        </div>
        <!-- Markup removed for brevity -->
        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Save" class="btn btn-default" />
            </div>
        </div>
    </div>
    <input name="__RequestVerificationToken" type="hidden" value="CfDJ8Inyxgp63fRFqUePGvuI5jGZsloJu1L7X9le1gy7NCIlSduCRx9jDQClrV9pOTTmqUyXnJBXhmrjcUVDJyDUMm7-MF_9rK8aAZdRdlOri7FmKVkRe_2v5LIHGKFcTjPrWPYnc9AdSbomkiOSaTEg7RU" />
</form>

Prvky <input> jsou v elementu HTML <form> , jehož action atribut je nastaven na publikování na /Movies/Edit/id adresu URL. Data formuláře se publikují na server po kliknutí na Save tlačítko. Poslední řádek před uzavíracím </form> prvkem zobrazuje skrytý token XSRF vygenerovaný pomocným pomocníkem značky formuláře.

Zpracování požadavku POST

Následující výpis ukazuje [HttpPost] verzi Edit metody akce.

// POST: Movies/Edit/5
// To protect from overposting attacks, enable the specific properties you want to bind to.
// For more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("Id,Title,ReleaseDate,Genre,Price,Rating")] Movie movie)
{
    if (id != movie.Id)
    {
        return NotFound();
    }

    if (ModelState.IsValid)
    {
        try
        {
            _context.Update(movie);
            await _context.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException)
        {
            if (!MovieExists(movie.Id))
            {
                return NotFound();
            }
            else
            {
                throw;
            }
        }
        return RedirectToAction(nameof(Index));
    }
    return View(movie);
}

Atribut [ValidateAntiForgeryToken] ověří skrytý token XSRF vygenerovaný generátorem tokenů proti padělání v pomocné rutině značky formuláře.

Systém vazby modelu přebírá publikované hodnoty formuláře a vytvoří Movie objekt, který se předává jako movie parametr. Vlastnost ModelState.IsValid ověřuje, že data odeslaná ve formuláři lze použít k úpravě (úpravě nebo aktualizaci) objektu Movie . Pokud jsou data platná, uloží se. Aktualizovaná (upravená) data videa se ukládají do databáze voláním SaveChangesAsync metody kontextu databáze. Po uložení dat kód přesměruje uživatele na Index metodu MoviesController akce třídy, která zobrazí kolekci filmů včetně právě provedených změn.

Než se formulář odešle na server, ověření na straně klienta zkontroluje všechna ověřovací pravidla v polích. Pokud dojde k nějakým chybám ověření, zobrazí se chybová zpráva a formulář se neúčtuje. Pokud je JavaScript zakázaný, nebudete mít ověření na straně klienta, ale server rozpozná publikované hodnoty, které nejsou platné, a hodnoty formuláře se znovu zobrazí s chybovými zprávami. Později v tomto kurzu podrobněji prozkoumáme ověření modelu. Pomocná rutina ověřovací značky v Views/Movies/Edit.cshtml šabloně zobrazení se postará o zobrazení odpovídajících chybových zpráv.

Zobrazení pro úpravy: Výjimka pro nesprávnou hodnotu Cena abc uvádí, že pole Cena musí být číslo. Výjimka pro nesprávnou hodnotu data vydání xyz stavů Zadejte platné datum.

HttpGet Všechny metody v řadiči videa se řídí podobným vzorem. Načte objekt videa (nebo seznam objektů v případě Index) a předají objekt (model) do zobrazení. Metoda Create předá do zobrazení prázdný objekt Create videa. Všechny metody, které vytvářejí, upravují, odstraňují nebo jinak upravují data, to dělají v [HttpPost] přetížení metody. Úprava dat v metodě HTTP GET představuje bezpečnostní riziko. Úprava dat v HTTP GET metodě také porušuje osvědčené postupy HTTP a vzor architektury REST , který určuje, že požadavky GET by neměly měnit stav vaší aplikace. Jinými slovy, provedení operace GET by měla být bezpečná operace, která nemá žádné vedlejší účinky a neupravuje trvalá data.

Další materiály

Máme dobrý začátek filmové aplikace, ale prezentace není ideální, například ReleaseDate by měla být dvě slova.

Zobrazení indexu: Datum vydání je jedno slovo (bez mezery) a každé datum vydání filmu ukazuje čas 12:00

Models/Movie.cs Otevřete soubor a přidejte zvýrazněné řádky uvedené níže:

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace MvcMovie.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; }
    }
}

DataAnnotations probereme v dalším kurzu. Atribut Display určuje, co se má zobrazit pro název pole (v tomto případě "Datum vydání" místo "ReleaseDate"). Atribut DataType určuje typ dat (Date), takže se nezobrazují informace o čase uloženém v poli.

Je vyžadována [Column(TypeName = "decimal(18, 2)")] datová poznámka, aby entity Framework Core bylo možné správně namapovat Price na měnu v databázi. Další informace naleznete v tématu Datové typy.

Přejděte na Movies kontroler a podržte ukazatel myši nad odkazem Pro úpravy a zobrazte cílovou adresu URL.

Okno prohlížeče s myší na odkaz Upravit a zobrazená adresa URL https://localhost:5001/Movies/Edit/5 odkazu

Odkazy Upravit, Podrobnosti a Odstranit jsou generovány pomocným rutinou základní značky ukotvení MVC v Views/Movies/Index.cshtml souboru.

        <a asp-action="Edit" asp-route-id="@item.ID">Edit</a> |
        <a asp-action="Details" asp-route-id="@item.ID">Details</a> |
        <a asp-action="Delete" asp-route-id="@item.ID">Delete</a>
    </td>
</tr>

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. Ve výše uvedeném AnchorTagHelper kódu dynamicky generuje hodnotu atributu HTML href z metody akce kontroleru a ID trasy. Ke zkoumání vygenerovaných značek použijete zobrazení zdroje z oblíbeného prohlížeče nebo použijete vývojářské nástroje. Část vygenerovaného kódu HTML je znázorněná níže:

 <td>
    <a href="/Movies/Edit/4"> Edit </a> |
    <a href="/Movies/Details/4"> Details </a> |
    <a href="/Movies/Delete/4"> Delete </a>
</td>

Vzpomeňte si formát pro směrování nastavený v Startup.cs souboru:

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllerRoute(
        name: "default",
        pattern: "{controller=Home}/{action=Index}/{id?}");
});

ASP.NET Core se přeloží https://localhost:5001/Movies/Edit/4 na požadavek na metodu EditMovies akce kontroleru s parametrem Id 4. (Metody kontroleru se označují také jako metody akcí.)

Další informace o pomocných rutinách značek najdete v tématu Další zdroje informací.

Movies Otevřete kontroler a prozkoumejte dvě Edit metody akcí. Následující kód ukazuje metodu HTTP GET Edit , která načte film a naplní formulář pro úpravy vygenerovaný souborem Edit.cshtmlRazor .

// GET: Movies/Edit/5
public async Task<IActionResult> Edit(int? id)
{
    if (id == null)
    {
        return NotFound();
    }

    var movie = await _context.Movie.FindAsync(id);
    if (movie == null)
    {
        return NotFound();
    }
    return View(movie);
}

Následující kód ukazuje metodu HTTP POST Edit , která zpracovává publikované hodnoty filmu:

// POST: Movies/Edit/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for 
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("ID,Title,ReleaseDate,Genre,Price")] Movie movie)
{
    if (id != movie.ID)
    {
        return NotFound();
    }

    if (ModelState.IsValid)
    {
        try
        {
            _context.Update(movie);
            await _context.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException)
        {
            if (!MovieExists(movie.ID))
            {
                return NotFound();
            }
            else
            {
                throw;
            }
        }
        return RedirectToAction("Index");
    }
    return View(movie);
}

Atribut [Bind] je jedním ze způsobů, jak chránit před nadměrným účtováním. Do atributu [Bind] , který chcete změnit, byste měli zahrnout pouze vlastnosti. Další informace naleznete v tématu Ochrana kontroleru před nadměrným publikováním. Modely ViewModel představují alternativní přístup, který zabrání nadměrnému účtování.

Všimněte si, že před atributem [HttpPost] předchází druhá Edit metoda akce.

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("ID,Title,ReleaseDate,Genre,Price")] Movie movie)
{
    if (id != movie.ID)
    {
        return NotFound();
    }

    if (ModelState.IsValid)
    {
        try
        {
            _context.Update(movie);
            await _context.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException)
        {
            if (!MovieExists(movie.ID))
            {
                return NotFound();
            }
            else
            {
                throw;
            }
        }
        return RedirectToAction(nameof(Index));
    }
    return View(movie);
}

Atribut HttpPost určuje, že tuto Edit metodu lze vyvolat pouze pro POST požadavky. Atribut můžete použít [HttpGet] u první metody úprav, ale to není nutné, protože [HttpGet] je to výchozí.

Atribut ValidateAntiForgeryToken se používá k zabránění padělání požadavku a je spárován s tokenem proti padělání vygenerovaném v souboru zobrazení pro úpravy (Views/Movies/Edit.cshtml). Soubor zobrazení pro úpravy vygeneruje token proti padělání pomocí pomocné rutiny značky formuláře.

<form asp-action="Edit">

Pomocník značky formuláře vygeneruje skrytý token proti padělání, který se musí shodovat s [ValidateAntiForgeryToken] vygenerovaným anti-forgery token v Edit metodě kontroleru Movies. Další informace najdete v tématu Prevence útoků založených na padělání žádosti posílané mezi weby (XSRF/CSRF) v ASP.NET Core.

Metoda HttpGet Edit vezme parametr filmu ID , vyhledá film pomocí metody Entity Framework FindAsync a vrátí vybraný film do zobrazení Pro úpravy. Pokud se video nenašlo, NotFound vrátí se (HTTP 404).

// GET: Movies/Edit/5
public async Task<IActionResult> Edit(int? id)
{
    if (id == null)
    {
        return NotFound();
    }

    var movie = await _context.Movie.FindAsync(id);
    if (movie == null)
    {
        return NotFound();
    }
    return View(movie);
}

Když systém generování uživatelského rozhraní vytvořil zobrazení Edit, prozkoumal Movie třídu a vytvořil kód pro vykreslení <label> a <input> prvky pro každou vlastnost třídy. Následující příklad ukazuje zobrazení pro úpravy vygenerované systémem generování uživatelského rozhraní sady Visual Studio:

@model MvcMovie.Models.Movie

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

<h1>Edit</h1>

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

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

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

Všimněte si, že šablona zobrazení obsahuje @model MvcMovie.Models.Movie příkaz v horní části souboru. @model MvcMovie.Models.Movie určuje, že zobrazení očekává model šablony zobrazení typu Movie.

Vygenerovaný kód používá několik pomocných metod značek ke zjednodušení kódu HTML. Pomocník značky popisku zobrazí název pole (Název, ReleaseDate, Žánr nebo Cena). Pomocné rutiny vstupní značky vykresluje element HTML<input>. Pomocník ověřovací značky zobrazí všechny ověřovací zprávy přidružené k této vlastnosti.

Spusťte aplikaci a přejděte na /Movies adresu URL. Klikněte na odkaz Upravit. V prohlížeči zobrazte zdroj stránky. Vygenerovaný kód HTML pro <form> element je zobrazen níže.

<form action="/Movies/Edit/7" method="post">
    <div class="form-horizontal">
        <h4>Movie</h4>
        <hr />
        <div class="text-danger" />
        <input type="hidden" data-val="true" data-val-required="The ID field is required." id="ID" name="ID" value="7" />
        <div class="form-group">
            <label class="control-label col-md-2" for="Genre" />
            <div class="col-md-10">
                <input class="form-control" type="text" id="Genre" name="Genre" value="Western" />
                <span class="text-danger field-validation-valid" data-valmsg-for="Genre" data-valmsg-replace="true"></span>
            </div>
        </div>
        <div class="form-group">
            <label class="control-label col-md-2" for="Price" />
            <div class="col-md-10">
                <input class="form-control" type="text" data-val="true" data-val-number="The field Price must be a number." data-val-required="The Price field is required." id="Price" name="Price" value="3.99" />
                <span class="text-danger field-validation-valid" data-valmsg-for="Price" data-valmsg-replace="true"></span>
            </div>
        </div>
        <!-- Markup removed for brevity -->
        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Save" class="btn btn-default" />
            </div>
        </div>
    </div>
    <input name="__RequestVerificationToken" type="hidden" value="CfDJ8Inyxgp63fRFqUePGvuI5jGZsloJu1L7X9le1gy7NCIlSduCRx9jDQClrV9pOTTmqUyXnJBXhmrjcUVDJyDUMm7-MF_9rK8aAZdRdlOri7FmKVkRe_2v5LIHGKFcTjPrWPYnc9AdSbomkiOSaTEg7RU" />
</form>

Prvky <input> jsou v elementu HTML <form> , jehož action atribut je nastaven na publikování na /Movies/Edit/id adresu URL. Data formuláře se publikují na server po kliknutí na Save tlačítko. Poslední řádek před uzavíracím </form> prvkem zobrazuje skrytý token XSRF vygenerovaný pomocným pomocníkem značky formuláře.

Zpracování požadavku POST

Následující výpis ukazuje [HttpPost] verzi Edit metody akce.

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("ID,Title,ReleaseDate,Genre,Price")] Movie movie)
{
    if (id != movie.ID)
    {
        return NotFound();
    }

    if (ModelState.IsValid)
    {
        try
        {
            _context.Update(movie);
            await _context.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException)
        {
            if (!MovieExists(movie.ID))
            {
                return NotFound();
            }
            else
            {
                throw;
            }
        }
        return RedirectToAction(nameof(Index));
    }
    return View(movie);
}

Atribut [ValidateAntiForgeryToken] ověří skrytý token XSRF vygenerovaný generátorem tokenů proti padělání v pomocné rutině značky formuláře.

Systém vazby modelu přebírá publikované hodnoty formuláře a vytvoří Movie objekt, který se předává jako movie parametr. Vlastnost ModelState.IsValid ověřuje, že data odeslaná ve formuláři lze použít k úpravě (úpravě nebo aktualizaci) objektu Movie . Pokud jsou data platná, uloží se. Aktualizovaná (upravená) data videa se ukládají do databáze voláním SaveChangesAsync metody kontextu databáze. Po uložení dat kód přesměruje uživatele na Index metodu MoviesController akce třídy, která zobrazí kolekci filmů včetně právě provedených změn.

Než se formulář odešle na server, ověření na straně klienta zkontroluje všechna ověřovací pravidla v polích. Pokud dojde k nějakým chybám ověření, zobrazí se chybová zpráva a formulář se neúčtuje. Pokud je JavaScript zakázaný, nebudete mít ověření na straně klienta, ale server rozpozná publikované hodnoty, které nejsou platné, a hodnoty formuláře se znovu zobrazí s chybovými zprávami. Později v tomto kurzu podrobněji prozkoumáme ověření modelu. Pomocná rutina ověřovací značky v Views/Movies/Edit.cshtml šabloně zobrazení se postará o zobrazení odpovídajících chybových zpráv.

Zobrazení pro úpravy: Výjimka pro nesprávnou hodnotu Cena abc uvádí, že pole Cena musí být číslo. Výjimka pro nesprávnou hodnotu data vydání xyz stavů Zadejte platné datum.

HttpGet Všechny metody v řadiči videa se řídí podobným vzorem. Načte objekt videa (nebo seznam objektů v případě Index) a předají objekt (model) do zobrazení. Metoda Create předá do zobrazení prázdný objekt Create videa. Všechny metody, které vytvářejí, upravují, odstraňují nebo jinak upravují data, to dělají v [HttpPost] přetížení metody. Úprava dat v metodě HTTP GET představuje bezpečnostní riziko. Úprava dat v HTTP GET metodě také porušuje osvědčené postupy HTTP a vzor architektury REST , který určuje, že požadavky GET by neměly měnit stav vaší aplikace. Jinými slovy, provedení operace GET by měla být bezpečná operace, která nemá žádné vedlejší účinky a neupravuje trvalá data.

Další materiály