Sdílet prostřednictvím


Přidání logiky ověřování do filmového modelu

Rick Anderson

Poznámka:

Aktualizovaná verze tohoto kurzu je k dispozici zde , která používá ASP.NET MVC 5 a Visual Studio 2013. Je bezpečnější, mnohem jednodušší sledovat a demonstrovat další funkce.

V této části přidáte do modelu logiku Movie ověření a zajistíte, že se ověřovací pravidla vynucují pokaždé, když se uživatel pokusí vytvořit nebo upravit film pomocí aplikace.

Udržování věcí suchých

Jeden ze základních návrhů principů ASP.NET MVC je SUCHÝ ("Neopakovat sami"). ASP.NET MVC doporučuje zadat funkce nebo chování pouze jednou a pak se projeví všude v aplikaci. Tím se sníží množství kódu, který potřebujete napsat, a kód, který napíšete, bude méně náchylný k chybám a usnadňuje údržbu.

Podpora ověřování poskytovaná ASP.NET MVC a Kód Entity Framework First je skvělým příkladem principu DRY v akci. Ověřovací pravidla můžete deklarativním způsobem zadat na jednom místě (ve třídě modelu) a pravidla se vynucují všude v aplikaci.

Podívejme se, jak můžete využít tuto podporu ověřování ve filmové aplikaci.

Přidání ověřovacích pravidel do filmového modelu

Začnete tím, že do třídy přidáte určitou logiku Movie ověření.

Otevřete soubor Movie.cs. using Na začátek souboru přidejte příkaz, který odkazuje na System.ComponentModel.DataAnnotations obor názvů:

using System.ComponentModel.DataAnnotations;

Všimněte si, že obor názvů neobsahuje System.Web. DataAnnotations poskytuje integrovanou sadu ověřovacích atributů, které můžete použít deklarativním způsobem na libovolnou třídu nebo vlastnost.

Nyní aktualizujte Movie třídu tak, aby využívala předdefinované Requiredatributy , StringLengtha Range ověřovací atributy. Jako příklad použití atributů použijte následující kód.

public class Movie {
    public int ID { get; set; }

    [Required]
    public string Title { get; set; }

    [DataType(DataType.Date)]
    public DateTime ReleaseDate { get; set; }

    [Required]
    public string Genre { get; set; }

    [Range(1, 100)]
    [DataType(DataType.Currency)]
    public decimal Price { get; set; }

    [StringLength(5)]
    public string Rating { get; set; }
}

Spusťte aplikaci a znovu se zobrazí následující chyba běhu:

Model, který zálohuje kontext MovieDBContext, se od vytvoření databáze změnil. Zvažte použití Migrace Code First k aktualizaci databáze (https://go.microsoft.com/fwlink/?LinkId=238269).

K aktualizaci schématu použijeme migrace. Sestavte řešení a otevřete okno konzoly Správce balíčků a zadejte následující příkazy:

add-migration AddDataAnnotationsMig
update-database

Po dokončení tohoto příkazu visual Studio otevře soubor třídy, který definuje novou DbMigration odvozenou třídu se zadaným názvem (AddDataAnnotationsMig) a v Up metodě uvidíte kód, který aktualizuje omezení schématu. Genre Pole Title už nejsou nullable (to znamená, že je nutné zadat hodnotu) a Rating pole má maximální délku 5.

Ověřovací atributy určují chování, které chcete vynutit u vlastností modelu, na které se použijí. Atribut Required označuje, že vlastnost musí mít hodnotu. V této ukázce musí film obsahovat hodnoty pro Title, ReleaseDate, Genrea Price vlastnosti, aby byly platné. Atribut Range omezuje hodnotu v konkrétním rozsahu. Atribut StringLength umožňuje nastavit maximální délku vlastnosti řetězce a volitelně její minimální délku. Vnitřní typy (například decimal, int, float, DateTime) jsou ve výchozím nastavení povinné a nepotřebují Required atribut.

Code First zajistí, aby se ověřovací pravidla zadaná pro třídu modelu vynucovali před uložením změn v databázi. Například následující kód vyvolá výjimku při SaveChanges zavolání metody, protože chybí několik požadovaných Movie hodnot vlastností a cena je nula (což je mimo platný rozsah).

MovieDBContext db = new MovieDBContext();

Movie movie = new Movie();
movie.Title = "Gone with the Wind";
movie.Price = 0.0M;

db.Movies.Add(movie);  
db.SaveChanges();        // <= Will throw server side validation exception  

Automatické vynucování ověřovacích pravidel rozhraním .NET Framework pomáhá zajistit robustnější aplikaci. Zajišťuje také, že nemůžete zapomenout něco ověřit a neúmyslně nechat do databáze chybná data.

Tady je úplný výpis kódu pro aktualizovaný soubor Movie.cs :

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

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

        [Required]
        public string Title { get; set; }

        [DataType(DataType.Date)]
        public DateTime ReleaseDate { get; set; }

        [Required]
        public string Genre { get; set; }

        [Range(1, 100)]
        [DataType(DataType.Currency)]
        public decimal Price { get; set; }

        [StringLength(5)]
        public string Rating { get; set; }
    }

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

Uživatelské rozhraní chyby ověřování v ASP.NET MVC

Znovu spusťte aplikaci a přejděte na adresu URL /Movies .

Kliknutím na odkaz Vytvořit nový přidáte nový film. Vyplňte formulář některými neplatnými hodnotami a klikněte na tlačítko Vytvořit .

8_validationErrors

Poznámka:

pokud chcete podporovat ověřování jQuery pro neanglické národní prostředí používající čárku (",") pro desetinnou čárku, musíte zahrnout globalize.js a konkrétní jazykové verze/globalize.cultures.js file(from https://github.com/jquery/globalize ) a JavaScript, aby bylo možné použít Globalize.parseFloat . Následující kód ukazuje úpravy souboru Views\Movies\Edit.cshtml pro práci s jazykovou verzí "fr-FR":

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
    <script src="~/Scripts/globalize.js"></script>
    <script src="~/Scripts/globalize.culture.fr-FR.js"></script>
    <script>
        $.validator.methods.number = function (value, element) {
            return this.optional(element) ||
                !isNaN(Globalize.parseFloat(value));
        }
        $(document).ready(function () {
            Globalize.culture('fr-FR');
        });
    </script>
    <script>
        jQuery.extend(jQuery.validator.methods, {    
            range: function (value, element, param) {        
                //Use the Globalization plugin to parse the value        
                var val = $.global.parseFloat(value);
                return this.optional(element) || (
                    val >= param[0] && val <= param[1]);
            }
        });

    </script>
}

Všimněte si, že formulář automaticky použil červenou barvu ohraničení ke zvýraznění textových polí obsahujících neplatná data a vygeneroval odpovídající chybovou zprávu ověření vedle každé z nich. Chyby se vynucují na straně klienta (pomocí JavaScriptu i jQuery) i na straně serveru (v případě, že má uživatel zakázaný JavaScript).

Skutečnou výhodou je, že k povolení tohoto ověřovacího uživatelského rozhraní nepotřebujete změnit jeden řádek kódu ve MoviesController třídě nebo v zobrazení Create.cshtml . Kontroler a zobrazení, které jste vytvořili dříve v tomto kurzu, automaticky získaly ověřovací pravidla, která jste určili pomocí ověřovacích atributů ve vlastnostech Movie třídy modelu.

Možná jste si všimli vlastností Title a Genrepožadovaný atribut se nevynucuje, dokud neodesíláte formulář (stiskněte tlačítko Vytvořit ), nebo nezadáte text do vstupního pole a neodeberete ho. U pole, které je zpočátku prázdné (například pole v zobrazení Vytvořit) a které má pouze požadovaný atribut a žádné další ověřovací atributy, můžete k aktivaci ověření provést následující:

  1. Přejděte tabulátorem do pole.
  2. Zadejte nějaký text.
  3. Vysouvte tabulátor.
  4. Vraťte se do pole tabulátorem.
  5. Odeberte text.
  6. Vysouvte tabulátor.

Výše uvedená sekvence aktivuje požadované ověření bez stisknutí tlačítka odeslat. Stačí, když stisknete tlačítko odeslat, aniž byste museli zadávat některá pole, aktivuje se ověření na straně klienta. Data formuláře se neodesílají na server, dokud nedojde k žádným chybám ověření na straně klienta. Můžete to otestovat vložením zarážky do metody HTTP Post nebo pomocí nástroje fiddler nebo vývojářských nástrojů IE 9 F12.

Snímek obrazovky znázorňující stránku Pro vytvoření videa V Výstraha vedle názvu uvádí, že pole Název je povinné. Výstraha vedle žánru uvádí, že pole Žánr je povinné.

Jak probíhá ověřování v metodě Vytvoření zobrazení a vytvoření akce

Možná vás zajímá, jak se vygenerovalo uživatelské rozhraní pro ověřování bez jakýchkoli aktualizací kódu v kontroleru nebo zobrazeních. Další výpis ukazuje, Create jak metody ve MovieController třídě vypadají. Nemění se na tom, jak jste je vytvořili dříve v tomto kurzu.

//
// GET: /Movies/Create

public ActionResult Create()
{
    return View();
}

//
// POST: /Movies/Create

[HttpPost]
public ActionResult Create(Movie movie)
{
    if (ModelState.IsValid)
    {
        db.Movies.Add(movie);
        db.SaveChanges();
        return RedirectToAction("Index");
    }

    return View(movie);
}

První metoda akce (HTTP GET) Create zobrazí počáteční formulář Pro vytvoření. Druhá ([HttpPost]) verze zpracovává příspěvek formuláře. Druhá Create metoda ( HttpPost verze) volá ModelState.IsValid , jestli má video nějaké chyby ověření. Volání této metody vyhodnotí všechny ověřovací atributy, které byly použity na objekt. Pokud objekt obsahuje chyby ověření, Create metoda formulář znovu zobrazí. Pokud nedojde k žádným chybám, metoda uloží nový film do databáze. V našem příkladu filmu, který používáme, není formulář publikován na server, pokud na straně klienta byly zjištěny chyby ověření; druhá Createmetoda se nikdy nevolá. Pokud v prohlížeči zakážete JavaScript, ověření klienta je zakázané a volání ModelState.IsValid metody HTTP POST Create pro kontrolu, jestli video obsahuje chyby ověření.

V metodě můžete nastavit zarážku HttpPost Create a ověřit, že metoda není nikdy volána, ověření na straně klienta neodesílá data formuláře při zjištění chyb ověření. Pokud v prohlížeči zakážete JavaScript, odešlete formulář s chybami, zobrazí se zarážka. Stále získáte úplné ověření bez JavaScriptu. Následující obrázek ukazuje, jak zakázat JavaScript v Internet Exploreru.

Snímek obrazovky znázorňující okno Možnosti internetu otevřené na kartě Zabezpečení Vlastní úroveň je zakroužkovaná červeně. V okně Nastavení zabezpečení je aktivní skriptování nastaveno na zakázání. Posuvník je zakroužkovaný červeně.

Snímek obrazovky znázorňující příspěvek H t t p Pokud je zvýrazněná tečka Stav modelu je platná.

Následující obrázek ukazuje, jak zakázat JavaScript v prohlížeči FireFox.

Snímek obrazovky s oknem Možnosti Je vybrán obsah a je zaškrtnuté políčko Povolit skript Java.

Následující obrázek ukazuje, jak zakázat JavaScript v prohlížeči Chrome.

Snímek obrazovky se stránkou Možnosti Pod kapotou je vybrán a zakroužkován červeně. V nastavení obsahu je Java Script nastaven na Povolit všem webům spustit Java Script.

Níže je šablona zobrazení Create.cshtml , kterou jste vygenerovali dříve v tomto kurzu. Používá se metodami akcí zobrazenými výše k zobrazení počátečního formuláře a k jeho opětovnému zobrazení v případě chyby.

@model MvcMovie.Models.Movie

@{
    ViewBag.Title = "Create";
}

<h2>Create</h2>

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")"></script>

@using (Html.BeginForm()) {
    @Html.ValidationSummary(true)

    <fieldset>
        <legend>Movie</legend>

        <div class="editor-label">
            @Html.LabelFor(model => model.Title)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Title)
            @Html.ValidationMessageFor(model => model.Title)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.ReleaseDate)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.ReleaseDate)
            @Html.ValidationMessageFor(model => model.ReleaseDate)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.Genre)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Genre)
            @Html.ValidationMessageFor(model => model.Genre)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.Price)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Price)
            @Html.ValidationMessageFor(model => model.Price)
        </div>
        <div class="editor-label">
    @Html.LabelFor(model => model.Rating)
</div>
<div class="editor-field">
    @Html.EditorFor(model => model.Rating)
    @Html.ValidationMessageFor(model => model.Rating)
</div>
        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

Všimněte si, jak kód používá pomocnou Html.EditorFor rutinu k výstupu elementu <input> pro každou Movie vlastnost. Vedle tohoto pomocníka Html.ValidationMessageFor je volání pomocné metody. Tyto dvě pomocné metody pracují s objektem modelu, který je předán kontrolerem do zobrazení (v tomto případě Movie objekt). Automaticky vyhledá ověřovací atributy zadané v modelu a podle potřeby zobrazí chybové zprávy.

Na tomto přístupu je opravdu hezké, že kontroler ani šablona pro vytvoření zobrazení nezná nic o skutečných ověřovacích pravidlech, která se vynucují, nebo o konkrétních zobrazených chybových zprávách. Ověřovací pravidla a chybové řetězce jsou určeny pouze ve Movie třídě. Stejná ověřovací pravidla se automaticky použijí pro zobrazení pro úpravy a všechny další šablony zobrazení, které můžete vytvořit, aby model upravily.

Pokud chcete logiku ověřování později změnit, můžete to udělat přesně na jednom místě přidáním ověřovacích atributů do modelu (v tomto příkladu movie třídy). Nemusíte se starat o různé části aplikace, které jsou nekonzistentní s tím, jak se pravidla vynucují – veškerá logika ověřování se definuje na jednom místě a bude použita všude. Díky tomu je kód velmi čistý a snadno se udržuje a vyvíjí. A znamená to, že budete plně dodržovat zásadu DRY.

Přidání formátování do filmového modelu

Otevřete soubor Movie.cs a prozkoumejte Movie třídu. Obor System.ComponentModel.DataAnnotations názvů poskytuje kromě předdefinované sady ověřovacích atributů i atributy formátování. Již jsme použili DataType hodnotu výčtu na datum vydání a na pole cen. Následující kód zobrazuje ReleaseDate vlastnosti a Price vlastnosti s příslušným DisplayFormat atributem.

[DataType(DataType.Date)] 
public DateTime ReleaseDate { get; set; }

[DataType(DataType.Currency)] 
public decimal Price { get; set; }

Atributy DataType nejsou ověřovací atributy, používají se k tomu, aby modul zobrazení řekl, jak vykreslit KÓD HTML. V předchozím příkladu DataType.Date atribut zobrazí data videa pouze jako kalendářní data bez času. Například následující DataType atributy neověřují formát dat:

[DataType(DataType.EmailAddress)]
[DataType(DataType.PhoneNumber)]
[DataType(DataType.Url)]

Výše uvedené atributy poskytují pouze nápovědy pro modul zobrazení k formátování dat (a zadání atributů, jako <> je adresa URL a <href="mailto:EmailAddress.com"> pro e-mail. K ověření formátu dat můžete použít atribut RegularExpression .

Alternativní přístup k používání DataType atributů můžete explicitně nastavit DataFormatString hodnotu. Následující kód ukazuje vlastnost data vydání s řetězcem formátu data (konkrétně "d"). Tuto možnost byste použili k určení, že nechcete časovat jako součást data vydání.

[DisplayFormat(DataFormatString = "{0:d}")]
public DateTime ReleaseDate { get; set; }

Kompletní Movie třída je zobrazena níže.

public class Movie {
    public int ID { get; set; }

    [Required]
    public string Title { get; set; }

    [DataType(DataType.Date)]
    public DateTime ReleaseDate { get; set; }

    [Required]
    public string Genre { get; set; }

    [Range(1, 100)]
    [DataType(DataType.Currency)]
    public decimal Price { get; set; }

    [StringLength(5)]
    public string Rating { get; set; }
}

Spusťte aplikaci a přejděte na Movies kontroler. Datum a cena vydání jsou pěkně formátované. Na následujícím obrázku je datum vydání a cena, které jako jazykovou verzi používají fr-FR.

8_format_SM

Následující obrázek ukazuje stejná data zobrazená s výchozí jazykovou verzí (ANGLIČTINA).

Snímek obrazovky znázorňující stránku indexu filmu V V C se čtyřmi uvedenými filmy

V další části série se podíváme na aplikaci a provedeme několik vylepšení automaticky generovaných Details a Delete metod.