Sdílet prostřednictvím


Zkoumání metod a zobrazení akcí úprav pro řadič videa

Rick Anderson

Poznámka:

Aktualizovaná verze tohoto kurzu je k dispozici zde pomocí nejnovější verze sady Visual Studio. Nový kurz používá ASP.NET Core MVC, který poskytuje mnoho vylepšení v tomto kurzu.

V tomto kurzu se naučíte ASP.NET Core MVC s řadiči a zobrazeními. Razor Pages je nová alternativa v ASP.NET Core, což je programovací model založený na stránkách, který usnadňuje a zvyšuje produktivitu vytváření webového uživatelského rozhraní. Doporučujeme vyzkoušet kurz Razor Pages před verzí MVC. Kurz Razor Pages:

  • Je jednodušší postupovat.
  • Obsahuje další funkce.
  • Je upřednostňovaným přístupem pro vývoj nových aplikací.

V této části prozkoumáte vygenerované Edit metody akcí a zobrazení řadiče videa. Ale nejdřív si dáme krátkou odvrácení, aby datum vydání vypadalo lépe. Otevřete soubor Models\Movie.cs a přidejte zvýrazněné řádky uvedené níže:

using System;
using System.ComponentModel.DataAnnotations;
using System.Data.Entity;

namespace MvcMovie.Models
{
    public class Movie
    {
        public int ID { get; set; }
        public string Title { get; set; }

        [Display(Name = "Release Date")]
        [DataType(DataType.Date)]
        [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
        public DateTime ReleaseDate { get; set; }
        public string Genre { get; set; }
        public decimal Price { get; set; }
    }

    public class MovieDBContext : DbContext
    {
        public DbSet<Movie> Movies { get; set; }
    }
}

Můžete také nastavit specifickou jazykovou verzi kalendářních dat, například takto:

[Display(Name = "Release Date")]
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:d}", ApplyFormatInEditMode = true)]
public DateTime ReleaseDate { 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, v tomto případě je to datum, takže informace o čase uložené v poli se nezobrazí. Atribut DisplayFormat je nutný pro chybu v prohlížeči Chrome, která nesprávně vykresluje formáty kalendářních dat.

Spusťte aplikaci a přejděte na Movies kontroler. Podržte ukazatel myši nad odkazem pro úpravy a zobrazte adresu URL, na kterou odkazuje.

EditLink_sm

Odkaz Edit byl vygenerován metodou Html.ActionLink v zobrazení Views\Movies\Index.cshtml :

@Html.ActionLink("Edit", "Edit", new { id=item.ID })

Html.ActionLink

Objekt Html je pomocná rutina, která je vystavena pomocí vlastnosti v Základní třídě System.Web.Mvc.WebViewPage . Metoda ActionLink pomocné rutiny usnadňuje dynamické generování hypertextových odkazů HTML, které odkazují na metody akcí na řadičích. Prvním argumentem ActionLink metody je text odkazu, který se má vykreslit (například <a>Edit Me</a>). Druhým argumentem je název metody akce, která se má vyvolat (v tomto případě akce Edit ). Posledním argumentem je anonymní objekt , který generuje směrovací data (v tomto případě ID 4).

Vygenerovaný odkaz zobrazený na předchozím obrázku je http://localhost:1234/Movies/Edit/4. Výchozí trasa (vytvořená v App_Start\RouteConfig.cs) přebírá vzor {controller}/{action}/{id}adresy URL . Proto ASP.NET převede http://localhost:1234/Movies/Edit/4 na požadavek na Edit metodu Movies akce kontroleru s parametrem ID rovnajícím se 4. Zkontrolujte následující kód ze souboru App_Start\RouteConfig.cs . Metoda MapRoute se používá ke směrování požadavků HTTP na správný kontroler a metodu akce a zadejte volitelný parametr ID. Metodu MapRoute používají také nástroje HtmlHelpers , jako ActionLink je generování adres URL s ohledem na kontroler, metodu akcí a všechna směrovací data.

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapRoute(
        name: "Default",
        url: "{controller}/{action}/{id}",
        defaults: new { controller = "Home", action = "Index", 
            id = UrlParameter.Optional }
    );
}

Parametry metody akce můžete předat také pomocí řetězce dotazu. Adresa URL http://localhost:1234/Movies/Edit?ID=3 například předá parametr ID 3 metodě Edit akce Movies kontroleru.

EditQueryString

Movies Otevřete kontroler. Níže jsou uvedené dvě Edit metody akcí.

// GET: /Movies/Edit/5
public ActionResult Edit(int? id)
{
    if (id == null)
    {
        return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
    }
    Movie movie = db.Movies.Find(id);
    if (movie == null)
    {
        return HttpNotFound();
    }
    return View(movie);
}

// POST: /Movies/Edit/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for 
// more details see https://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include="ID,Title,ReleaseDate,Genre,Price")] Movie movie)
{
    if (ModelState.IsValid)
    {
        db.Entry(movie).State = EntityState.Modified;
        db.SaveChanges();
        return RedirectToAction("Index");
    }
    return View(movie);
}

Všimněte si, že před atributem HttpPost předchází druhá Edit metoda akce. Tento atribut určuje, že přetížení Edit metody lze vyvolat pouze pro požadavky POST. Atribut můžete použít HttpGet u první metody úprav, ale to není nutné, protože je to výchozí. (Budeme odkazovat na metody akcí, které jsou implicitně přiřazeny HttpGet atributu jako HttpGet metody.) Atribut Bind je dalším důležitým mechanismem zabezpečení, který hackerům brání v nadměrném publikování dat do vašeho modelu. Do atributu vazby, který chcete změnit, byste měli zahrnout pouze vlastnosti. Můžete si přečíst o overpostingu a atribut vazby v mé nadpřijetí bezpečnostní poznámky. V jednoduchém modelu použitém v tomto kurzu vytvoříme vazbu všech dat v modelu. Atribut ValidateAntiForgeryToken slouží k zabránění padělání požadavku a je spárován se souborem @Html.AntiForgeryToken() zobrazení pro úpravy (Views\Movies\Edit.cshtml), který je uveden níže:

@model MvcMovie.Models.Movie

@{
    ViewBag.Title = "Edit";
}
<h2>Edit</h2>
@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()    
    <div class="form-horizontal">
        <h4>Movie</h4>
        <hr />
        @Html.ValidationSummary(true)
        @Html.HiddenFor(model => model.ID)

        <div class="form-group">
            @Html.LabelFor(model => model.Title, new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Title)
                @Html.ValidationMessageFor(model => model.Title)
            </div>
        </div>

@Html.AntiForgeryToken() generuje skrytý anti-gery token formuláře, který se musí shodovat v Edit metodě Movies kontroleru. Další informace o padělání žádostí mezi weby (označované také jako XSRF nebo CSRF) najdete v mém kurzu XSRF/CSRF Prevence v MVC.

Metoda HttpGet Edit přebírá parametr ID videa, vyhledá film pomocí metody Entity Framework Find a vrátí vybraný film do zobrazení Edit. Pokud nelze najít video, vrátí se HttpNotFound . 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

@{
    ViewBag.Title = "Edit";
}
<h2>Edit</h2>
@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()    
    <div class="form-horizontal">
        <h4>Movie</h4>
        <hr />
        @Html.ValidationSummary(true)
        @Html.HiddenFor(model => model.ID)

        <div class="form-group">
            @Html.LabelFor(model => model.Title, new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Title)
                @Html.ValidationMessageFor(model => model.Title)
            </div>
        </div>
        <div class="form-group">
            @Html.LabelFor(model => model.ReleaseDate, new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.ReleaseDate)
                @Html.ValidationMessageFor(model => model.ReleaseDate)
            </div>
        </div>
        @*Genre and Price 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>
}
<div>
    @Html.ActionLink("Back to List", "Index")
</div>
@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

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

Vygenerovaný kód používá několik pomocných metod ke zjednodušení kódu HTML. Pomocník Html.LabelFor zobrazí název pole (Název, Datum vydání, Žánr nebo Cena). Pomocník Html.EditorFor vykreslí element HTML <input> . Pomocník Html.ValidationMessageFor zobrazí všechny ověřovací zprávy přidružené k této vlastnosti.

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

<form action="/movies/Edit/4" method="post">
   <input name="__RequestVerificationToken" type="hidden" value="UxY6bkQyJCXO3Kn5AXg-6TXxOj6yVBi9tghHaQ5Lq_qwKvcojNXEEfcbn-FGh_0vuw4tS_BRk7QQQHlJp8AP4_X4orVNoQnp2cd8kXhykS01" />  <fieldset class="form-horizontal">
      <legend>Movie</legend>

      <input data-val="true" data-val-number="The field ID must be a number." data-val-required="The ID field is required." id="ID" name="ID" type="hidden" value="4" />

      <div class="control-group">
         <label class="control-label" for="Title">Title</label>
         <div class="controls">
            <input class="text-box single-line" id="Title" name="Title" type="text" value="GhostBusters" />
            <span class="field-validation-valid help-inline" data-valmsg-for="Title" data-valmsg-replace="true"></span>
         </div>
      </div>

      <div class="control-group">
         <label class="control-label" for="ReleaseDate">Release Date</label>
         <div class="controls">
            <input class="text-box single-line" data-val="true" data-val-date="The field Release Date must be a date." data-val-required="The Release Date field is required." id="ReleaseDate" name="ReleaseDate" type="date" value="1/1/1984" />
            <span class="field-validation-valid help-inline" data-valmsg-for="ReleaseDate" data-valmsg-replace="true"></span>
         </div>
      </div>

      <div class="control-group">
         <label class="control-label" for="Genre">Genre</label>
         <div class="controls">
            <input class="text-box single-line" id="Genre" name="Genre" type="text" value="Comedy" />
            <span class="field-validation-valid help-inline" data-valmsg-for="Genre" data-valmsg-replace="true"></span>
         </div>
      </div>

      <div class="control-group">
         <label class="control-label" for="Price">Price</label>
         <div class="controls">
            <input class="text-box single-line" 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" type="text" value="7.99" />
            <span class="field-validation-valid help-inline" data-valmsg-for="Price" data-valmsg-replace="true"></span>
         </div>
      </div>

      <div class="form-actions no-color">
         <input type="submit" value="Save" class="btn" />
      </div>
   </fieldset>
</form>

Prvky <input> jsou v elementu HTML <form> , jehož action atribut je nastaven pro publikování na adresu URL /Movies/Edit . Data formuláře se publikují na server po kliknutí na tlačítko Uložit . Druhý řádek zobrazuje skrytý token XSRF vygenerovaný voláním @Html.AntiForgeryToken() .

Zpracování požadavku POST

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

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include="ID,Title,ReleaseDate,Genre,Price")] Movie movie)
{
    if (ModelState.IsValid)
    {
        db.Entry(movie).State = EntityState.Modified;
        db.SaveChanges();
        return RedirectToAction("Index");
    }
    return View(movie);
}

Atribut ValidateAntiForgeryToken ověří token XSRF vygenerovaný voláním @Html.AntiForgeryToken() v zobrazení.

Pořadač modelu ASP.NET MVC přebírá publikované hodnoty formuláře a vytvoří Movie objekt, který se předá jako movie parametr. ModelState.IsValid Ověřuje, že data odeslaná ve formuláři lze použít k úpravě (úpravě nebo aktualizaci) objektuMovie. Pokud jsou data platná, uloží se data videa do Movies kolekce db(MovieDBContext instance). Nová data videa jsou uložena do databáze voláním SaveChanges metody MovieDBContext. 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.

Jakmile ověření na straně klienta zjistí, že hodnota pole není platná, zobrazí se chybová zpráva. Pokud je JavaScript zakázaný, ověření na straně klienta je zakázané. Server však zjistí, že publikované hodnoty nejsou platné a hodnoty formuláře se znovu zobrazí s chybovými zprávami.

Ověření se podrobněji zkoumá později v tomto kurzu.

Pomocné Html.ValidationMessageFor rutiny v šabloně zobrazení Edit.cshtml se postará o zobrazení odpovídajících chybových zpráv.

abcNotValid

HttpGet Všechny metody se řídí podobným vzorem. Načte objekt videa (nebo seznam objektů v případě Index) a předají model do zobrazení. Metoda Create předá prázdný objekt filmu do zobrazení Create. 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 metodě GET 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.

Ověřování jQuery pro neanglické národní prostředí

Pokud používáte počítač s angličtinou v USA, můžete tuto část přeskočit a přejít k dalšímu kurzu. Verzi tohoto kurzu si můžete stáhnout zde. Vynikající dvoudílný kurz o internationalizaci, viz Nadeem ASP.NET MVC 5 Internationalization.

Poznámka:

pokud chcete podporovat ověřování jQuery pro neanglické národní prostředí, které používají čárku (",") pro desetinnou čárku a jiné formáty kalendářních dat než v ANGLIČTINĚ, musíte zahrnout globalize.js a konkrétní jazykové verze/globalize.cultures.js file(z https://github.com/jquery/globalize ) a JavaScript, aby bylo možné použít Globalize.parseFloat. Ověření jQuery bez angličtiny můžete získat z NuGetu. (Neinstalujte globalizaci, pokud používáte anglické národní prostředí.)

  1. V nabídce Nástroje klepněte na NuGet Správce balíčků a potom klepněte na tlačítko Spravovat balíčky NuGet pro řešení.

    Snímek obrazovky s nabídkou Nástroje pro zahájení ověřování jQuery pro neanglické národní prostředí

  2. V levém podokně vyberte Procházet*.*(Viz obrázek níže.)

  3. Do vstupního pole zadejte Globalize*.

    Snímek obrazovky se vstupním polem pro zadání globalizace

    Zvolte jQuery.Validation.Globalize, zvolte MvcMovie a klikněte na Nainstalovat. Do projektu se přidá soubor Scripts\jquery.globalize\globalize.js . Složka *Scripts\jquery.globalize\cultures* bude obsahovat mnoho jazykových souborů JavaScriptu. Upozorňujeme, že instalace tohoto balíčku může trvat pět minut.

    Následující kód ukazuje úpravy souboru Views\Movies\Edit.cshtml:

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")

<script src="~/Scripts/globalize/globalize.js"></script>
<script src="~/Scripts/globalize/cultures/globalize.culture.@(System.Threading.Thread.CurrentThread.CurrentCulture.Name).js"></script>
<script>
    $.validator.methods.number = function (value, element) {
        return this.optional(element) ||
            !isNaN(Globalize.parseFloat(value));
    }
    $(document).ready(function () {
        Globalize.culture('@(System.Threading.Thread.CurrentThread.CurrentCulture.Name)');
    });
</script>
<script>
    jQuery.extend(jQuery.validator.methods, {
        range: function (value, element, param) {
            //Use the Globalization plugin to parse the value
            var val = Globalize.parseFloat(value);
            return this.optional(element) || (
                val >= param[0] && val <= param[1]);
        }
    });
    $.validator.methods.date = function (value, element) {
        return this.optional(element) ||
            Globalize.parseDate(value) ||
            Globalize.parseDate(value, "yyyy-MM-dd");
    }
</script>
}

Abyste se vyhnuli opakování tohoto kódu v každém zobrazení pro úpravy, můžete ho přesunout do souboru rozložení. Pokud chcete optimalizovat stahování skriptu, prohlédnu si můj kurz Sdružování a minifikace.

Další informace naleznete v tématu ASP.NET MVC 3 Internationalization and ASP.NET MVC 3 Internationalization - Part 2 (NerdDinner).

Jako dočasná oprava platí, že pokud ve svém národním prostředí nemůžete získat ověřování, můžete vynutit, aby počítač používal angličtinu v USA, nebo můžete v prohlížeči zakázat JavaScript. Chcete-li vynutit, aby váš počítač používal angličtinu v USA, můžete přidat element globalizace do kořenového souboru web.config projektů. Následující kód ukazuje element globalizace s jazykovou verzí nastavenou na USA angličtina.

<system.web>
    <globalization culture ="en-US" />
    <!--elements removed for clarity-->
  </system.web>

V dalším kurzu implementujeme funkce vyhledávání.