Přidání logiky ověřování do filmového modelu
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é Required
atributy , StringLength
a 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
, Genre
a 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 .
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 Genre
pož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í:
- Přejděte tabulátorem do pole.
- Zadejte nějaký text.
- Vysouvte tabulátor.
- Vraťte se do pole tabulátorem.
- Odeberte text.
- 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.
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á Create
metoda 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.
Následující obrázek ukazuje, jak zakázat JavaScript v prohlížeči FireFox.
Následující obrázek ukazuje, jak zakázat JavaScript v prohlížeči Chrome.
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.
Následující obrázek ukazuje stejná data zobrazená s výchozí jazykovou verzí (ANGLIČTINA).
V další části série se podíváme na aplikaci a provedeme několik vylepšení automaticky generovaných Details
a Delete
metod.