Sdílet prostřednictvím


Přidání ověření

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 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

Jednou ze základních principů návrhu ASP.NET MVC je DRY ("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. Všimněte si, že System.ComponentModel.DataAnnotations 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. (Obsahuje také atributy formátování, jako je Datový typ , který pomáhá s formátováním a neposkytuje žádné ověření.)

Nyní aktualizujte Movie třídu, aby využila Requiredvýhod integrovaných , , StringLengthRegularExpression a Range ověřovacích atributů. Movie Nahraďte třídu následujícím kódem:

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

    [StringLength(60, MinimumLength = 3)]
    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; }
  
    [RegularExpression(@"^[A-Z]+[a-zA-Z]*$")]
    [Required]
    [StringLength(30)]
    public string Genre { get; set; }

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

    [RegularExpression(@"^[A-Z]+[a-zA-Z]*$")]
    [StringLength(5)]
    public string Rating { get; set; }
}

Atribut StringLength nastaví maximální délku řetězce a nastaví toto omezení pro databázi, a proto se schéma databáze změní. Klikněte pravým tlačítkem myši na tabulku Filmy v Průzkumníku serveru a klikněte na Otevřít definici tabulky:

Snímek obrazovky s otevřeným oknem Průzkumníka serveru a na kartě d b o tečka Movies Design

Na obrázku výše vidíte, že všechna řetězcová pole jsou nastavená na NVARCHAR (MAX). 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 DataAnnotations
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 (DataAnnotations) a v Up metodě uvidíte kód, který aktualizuje omezení schématu:

public override void Up()
{
    AlterColumn("dbo.Movies", "Title", c => c.String(maxLength: 60));
    AlterColumn("dbo.Movies", "Genre", c => c.String(nullable: false, maxLength: 30));
    AlterColumn("dbo.Movies", "Rating", c => c.String(maxLength: 5));
}

Pole Genre už nemá hodnotu null (to znamená, že je nutné zadat hodnotu). Pole Rating má maximální délku 5 a Title má maximální délku 60. Minimální délka 3 zapnutá Title a rozsah nevytvořil Price změny schématu.

Prozkoumejte schéma Filmu:

Snímek obrazovky znázorňující kartu d b o tečka Movies Design Název a hodnocení jsou zaškrtnuté ve sloupci Povolit hodnoty Null.

Pole řetězců zobrazují nové limity délky a Genre už nejsou zaškrtnutá jako nullable.

Ověřovací atributy určují chování, které chcete vynutit u vlastností modelu, na které se použijí. MinimumLength Atributy Required označují, že vlastnost musí mít hodnotu, ale nic nebrání uživateli v zadání prázdného místa, aby toto ověření splnil. Atribut RegularExpression se používá k omezení, které znaky mohou být vstupní. V kódu výše Genre a Rating musí používat pouze písmena (prázdné znaky, číslice a speciální znaky nejsou povoleny). 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. Typy hodnot (například decimal, int, float, DateTime) jsou ze své podstaty 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 DbEntityValidationException při SaveChanges zavolání metody, protože chybí několik požadovaných Movie hodnot vlastností:

MovieDBContext db = new MovieDBContext();
Movie movie = new Movie();
movie.Title = "Gone with the Wind";
db.Movies.Add(movie);
db.SaveChanges();        // <= Will throw server side validation exception

Výše uvedený kód vyvolá následující výjimku:

Ověření u jedné nebo více entit se nezdařilo. Další podrobnosti najdete v části Vlastnost EntityValidationErrors.

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.

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

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. Jakmile ověření na straně klienta jQuery zjistí chybu, zobrazí se chybová zpráva.

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 globalizaci NuGet, jak je popsáno výše v tomto kurzu.

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. Otestujte ověření pomocí Edit metody akce a použije se stejné ověření.

Data formuláře se neodesílají na server, dokud nedojde k žádným chybám ověření na straně klienta. Můžete to ověřit tak, že do metody HTTP Post umístíte zarážku pomocí nástroje fiddler nebo vývojářských nástrojů IE F12.

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.

public ActionResult Create()
{
    return View();
}
// POST: /Movies/Create
// 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 Create([Bind(Include = "ID,Title,ReleaseDate,Genre,Price,Rating")] 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) zkontroluje ModelState.IsValid , jestli video obsahuje nějaké chyby ověření. Získání této vlastnosti vyhodnotí všechny ověřovací atributy, které byly použity na objekt. Pokud objekt obsahuje chyby ověření, Create metoda znovu zobrazí formulář. Pokud nedojde k žádným chybám, metoda uloží nový film do databáze. V našem příkladu filmu není formulář publikován na server, pokud jsou na straně klienta zjištěny chyby ověření; druhá Create metoda se nikdy nevolá. Pokud v prohlížeči zakážete JavaScript, ověření klienta je zakázané a metoda HTTP POST Create zkontroluje ModelState.IsValid , 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 s otevřeným oknem Možnosti internetu a na kartě Zabezpečení Okno Vlastní úroveň je otevřené a aktivní skriptování je zakázané.

Snímek obrazovky znázorňující příspěvek H t t p a pokud je zvýrazněná tečka stavu modelu

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

Snímek obrazovky s oknem Možnosti Obsah je vybraný a povolení java skriptu je zakroužkováno červeně.

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

Snímek obrazovky s nastavením Java Script a možností pro povolení nebo zakázání

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>
@using (Html.BeginForm()) 
{
    @Html.AntiForgeryToken()    
    <div class="form-horizontal">
        <h4>Movie</h4>
        <hr />
        @Html.ValidationSummary(true)
        <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>
        @*Fields removed for brevity.*@        




        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Create" 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, 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.

To, co je v tomto přístupu opravdu hezké, je, že kontroler ani Create šablona zobrazení neví 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í v Edit zobrazení a všechny ostatní šablony zobrazení, které můžete vytvořit, aby model upravte.

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 .

Použití atributů datového typu

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 DataType atributem.

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

Atributy DataType poskytují pouze nápovědu pro modul zobrazení k formátování dat (a zadávání atributů, jako <a> jsou adresy URL a <a href="mailto:EmailAddress.com"> e-mail). K ověření formátu dat můžete použít atribut RegularExpression . Atribut DataType slouží k určení datového typu, který je konkrétnější než vnitřní typ databáze, nejsou ověřovacími atributy. V tomto případě chceme sledovat pouze datum, nikoli datum a čas. Výčet DataType poskytuje mnoho datových typů, jako je datum, čas, telefonní číslo, měna, EmailAddress a další. Atribut DataType může také aplikaci povolit, aby automaticky poskytovala funkce specifické pro typ. Odkaz lze například mailto: vytvořit pro DataType.EmailAddress a pro DataType.Date lze v prohlížečích podporujících HTML5 zadat selektor data. Atributy DataType generují atributy HTML 5 data- (vyslovuje se pomlčka), které můžou prohlížeče HTML 5 pochopit. Atributy DataType neposkytují žádné ověření.

DataType.Date nezadá formát zobrazeného data. Ve výchozím nastavení se datové pole zobrazí podle výchozích formátů založených na souboru CultureInfo serveru.

Atribut DisplayFormat se používá k explicitní zadání formátu data:

[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime EnrollmentDate { get; set; }

Nastavení ApplyFormatInEditMode určuje, že zadané formátování se má použít také při zobrazení hodnoty v textovém poli pro úpravy. (U některých polí to možná nechcete – například pro hodnoty měny, nemusíte chtít symbol měny v textovém poli pro úpravy.)

Atribut DisplayFormat můžete použít samostatně, ale obecně je vhodné použít také atribut DataType. Atribut DataType vyjadřuje sémantiku dat na rozdíl od toho, jak je vykreslit na obrazovce, a poskytuje následující výhody, se DisplayFormatkterými se nedostanete:

  • Prohlížeč může povolit funkce HTML5 (například zobrazení ovládacího prvku kalendáře, symbol měny odpovídající národnímu prostředí, e-mailové odkazy atd.).
  • Ve výchozím nastavení prohlížeč vykresluje data pomocí správného formátu na základě vašeho národního prostředí.
  • Atribut DataType umožňuje MVC zvolit správnou šablonu pole pro vykreslení dat ( DisplayFormat , pokud používá sám sebe, používá šablonu řetězce). Další informace najdete v tématu Brad Wilson's ASP.NET MVC 2 Templates. (I když je napsaný pro MVC 2, tento článek se stále vztahuje na aktuální verzi ASP.NET MVC.)

Pokud atribut používáte DataType s polem kalendářního data, musíte atribut zadat DisplayFormat také, aby se pole vykreslovaly správně v prohlížečích Chrome. Další informace najdete v tomto vlákně StackOverflow.

Poznámka:

Ověřování jQuery nefunguje s atributem Range a DateTime. Následující kód například vždy zobrazí chybu ověření na straně klienta, i když je datum v zadaném rozsahu:

[Range(typeof(DateTime), "1/1/1966", "1/1/2020")]

Abyste mohli použít atribut Range s datem DateTime, budete muset zakázat ověření data jQuery. Obecně není vhodné zkompilovat pevná data v modelech, takže použití atributu Range a DateTime se nedoporučuje.

Následující kód ukazuje kombinování atributů na jednom řádku:

public class Movie
{
   public int ID { get; set; }
   [Required,StringLength(60, MinimumLength = 3)]
   public string Title { get; set; }
   [Display(Name = "Release Date"),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; }
   [Required,StringLength(5)]
   public string Rating { get; set; }
}

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