Přidání ověření do modelu (C#)

Rick Anderson

Poznámka

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

V tomto kurzu se naučíte základy sestavení webové aplikace ASP.NET MVC pomocí sady Microsoft Visual Web Developer 2010 Express Service Pack 1, což je bezplatná verze sady Microsoft Visual Studio. Než začnete, ujistěte se, že jste nainstalovali níže uvedené požadavky. Všechny z nich můžete nainstalovat kliknutím na následující odkaz: Instalační program webové platformy. Případně můžete požadavky nainstalovat jednotlivě pomocí následujících odkazů:

Pokud používáte Visual Studio 2010 místo Sady Visual Web Developer 2010, nainstalujte požadované součásti kliknutím na následující odkaz: Požadavky sady Visual Studio 2010.

K tomuto tématu je k dispozici projekt Visual Web Developer se zdrojovým kódem jazyka C#. Stáhněte si verzi jazyka C#. Pokud dáváte přednost jazyku Visual Basic, přepněte na verzi Visual Basic tohoto kurzu.

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

Udržování věcí v suchu

Jednou ze základních principů návrhu ASP.NET MVC je DRY (Neopakovat se). ASP.NET MVC doporučuje zadat funkčnost nebo chování pouze jednou a pak se to projeví všude v aplikaci. Tím se sníží množství kódu, který potřebujete napsat, a usnadní se údržba kódu, který píšete.

Skvělým příkladem principu DRY v praxi je podpora ověřování poskytovaná ASP.NET MVC a Entity Framework Code First. Ověřovací pravidla můžete deklarativně zadat na jednom místě (ve třídě modelu) a pak se tato pravidla vynucují všude v aplikaci.

Pojďme se podívat, 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 přidáním ověřovací logiky Movie do třídy.

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;

Obor názvů je součástí rozhraní .NET Framework. Poskytuje integrovanou sadu ověřovacích atributů, které můžete deklarativně použít na libovolnou třídu nebo vlastnost.

Teď aktualizujte Movie třídu tak, aby využívala předdefinované StringLengthRequiredatributy , a Range ověřovací atributy. Jako příklad, kde se mají atributy použít, použijte následující kód.

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

    [Required(ErrorMessage = "Title is required")]
    public string Title { get; set; }

    [Required(ErrorMessage = "Date is required")]
    public DateTime ReleaseDate { get; set; }

    [Required(ErrorMessage = "Genre must be specified")]
    public string Genre { get; set; }

    [Range(1, 100, ErrorMessage = "Price must be between $1 and $100")]
    public decimal Price { get; set; }

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

Ověřovací atributy určují chování, které chcete vynutit u vlastností modelu, na které jsou použity. Atribut Required označuje, že vlastnost musí mít hodnotu. V této ukázce musí film obsahovat hodnoty vlastností Title, ReleaseDate, Genrea Price , 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.

Code First zajišťuje, aby ověřovací pravidla, která zadáte pro třídu modelu, byla vynucována před tím, než aplikace uloží změny 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 nulová (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 validation exception

Díky automatickému vynucování ověřovacích pravidel rozhraním .NET Framework je vaše aplikace robustnější. Zajišťuje také, že nemůžete zapomenout něco ověřit a neúmyslně pustit do databáze špatná 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(ErrorMessage = "Title is required")]
        public string Title { get; set; }

        public DateTime ReleaseDate { get; set; }

        [Required(ErrorMessage = "Genre must be specified")]
        public string Genre { get; set; }

        [Range(1, 100, ErrorMessage = "Price must be between $1 and $100")]
        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í s chybou ověření v ASP.NET MVC

Spusťte aplikaci znovu a přejděte na adresu URL /Movies .

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

8_validationErrors

Všimněte si, že formulář automaticky použil barvu pozadí ke zvýraznění textových polí obsahujících neplatná data a vedle každého z nich vygeneroval příslušnou ověřovací chybovou zprávu. Chybové zprávy odpovídají chybovým řetězcům, které jste zadali při anotování Movie třídy. Chyby se vynucují na straně klienta (pomocí JavaScriptu) i na straně serveru (v případě, že má uživatel zakázaný JavaScript).

Skutečnou výhodou je, že jste nemuseli měnit jeden řádek kódu ve MoviesController třídě nebo v zobrazení Create.cshtml , abyste toto ověřovací uživatelské rozhraní povolili. Kontroler a zobrazení, které jste vytvořili dříve v tomto kurzu, automaticky převzaly ověřovací pravidla, která jste zadali pomocí atributů ve Movie třídě modelu.

Jak probíhá ověření v metodě Vytvořit zobrazení a Vytvořit akci

Možná vás zajímá, jak se vygenerovalo ověřovací uživatelské rozhraní bez jakýchkoli aktualizací kódu v kontroleru nebo zobrazeních. Další výpis ukazuje, jak Create metody ve MovieController třídě vypadají. Nemění se oproti tomu, 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 zobrazí počáteční formulář Vytvořit. Druhý zpracovává příspěvek formuláře. Druhá Create metoda volá ModelState.IsValid , aby zkontrolovala, jestli video obsahuje nějaké chyby ověřování. Volání této metody vyhodnocuje všechny ověřovací atributy, které byly použity na objekt. Pokud má objekt chyby ověření, Create metoda formulář znovu zobrazí. Pokud nedojde k žádným chybám, metoda uloží nové video do databáze.

Níže je šablona zobrazení Create.cshtml , kterou jste vygenerovali dříve v tomto kurzu. Používají ho metody akcí uvedené 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")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></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 je volání Html.ValidationMessageFor pomocné metody. Tyto dvě pomocné metody pracují s objektem modelu, který kontroler předává zobrazení (v tomto případě objektu Movie ). Automaticky vyhledá ověřovací atributy zadané v modelu a podle potřeby zobrazí chybové zprávy.

Na tomto přístupu je opravdu pěkné, že kontroler ani šablona zobrazení pro vytvoření neví nic o vynucovaných skutečných ověřovacích pravidlech nebo o konkrétních zobrazených chybových zprávách. Ověřovací pravidla a chybové řetězce jsou zadané pouze ve Movie třídě.

Pokud chcete později změnit logiku ověřování, můžete to udělat přesně na jednom místě. Nebudete si muset dělat starosti s tím, že různé části aplikace budou nekonzistentní s tím, jak se pravidla vynucují – veškerá logika ověřování se definuje na jednom místě a použije se všude. Díky tomu je kód velmi čistý a snadno se udržuje a vyvíjí. A znamená to, že budete plně respektovat princip DRY.

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

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

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

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

Případně můžete explicitně nastavit DataFormatString hodnotu. Následující kód zobrazuje vlastnost data vydání s řetězcem formátu data (konkrétně "d"). Pomocí tohoto příkazu určíte, že v rámci data vydání nechcete mít čas.

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

Následující kód naformátuje Price vlastnost jako měnu.

[DisplayFormat(DataFormatString = "{0:c}")]
public decimal Price { get; set; }

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

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

    [Required(ErrorMessage = "Title is required")]
    public string Title { get; set; }

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

    [Required(ErrorMessage = "Genre must be specified")]
    public string Genre { get; set; }

    [Range(1, 100, ErrorMessage = "Price must be between $1 and $100")]
    [DisplayFormat(DataFormatString = "{0:c}")]
    public decimal Price { get; set; }

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

Spusťte aplikaci a přejděte na Movies kontroler.

8_format_SM

V další části série si aplikaci projdeme a vylepšujeme automaticky generované Details metody a Delete metody.