Ověřování v rozhraní IDataErrorInfo (C#)
Stephen Walther ukazuje, jak zobrazit vlastní chybové zprávy ověřování implementací rozhraní IDataErrorInfo ve třídě modelu.
Cílem tohoto kurzu je vysvětlit jeden přístup k ověřování v aplikaci ASP.NET MVC. Dozvíte se, jak někomu zabránit v odeslání formuláře HTML bez zadání hodnot pro povinná pole formuláře. V tomto kurzu se naučíte provádět ověřování pomocí rozhraní IErrorDataInfo.
Předpoklady
V tomto kurzu použiju databázi MoviesDB a tabulku databáze Movies. Tato tabulka obsahuje následující sloupce:
Název sloupce | Datový typ | Povolit hodnoty Null |
---|---|---|
Id | Int | Ne |
Nadpis | Nvarchar(100) | Ne |
Ředitel | Nvarchar(100) | Ne |
DatumVydané | DateTime | Ne |
V tomto kurzu používám Microsoft Entity Framework k vygenerování tříd databázového modelu. Třída Movie vygenerovaná rozhraním Entity Framework je zobrazena na obrázku 1.
Obrázek 01: Entita Film (kliknutím zobrazíte obrázek v plné velikosti)
Poznámka
Další informace o použití Entity Frameworku k vygenerování tříd modelu databáze najdete v mém kurzu s názvem Vytváření tříd modelů pomocí Entity Frameworku.
Třída kontroleru
K zobrazení seznamu filmů a vytváření nových filmů používáme ovladač Domů. Kód pro tuto třídu je obsažen v výpisu 1.
Výpis 1 – Controllers\HomeController.cs
using System.Linq;
using System.Web.Mvc;
using MvcApplication1.Models;
namespace MvcApplication1.Controllers
{
public class HomeController : Controller
{
private MoviesDBEntities _db = new MoviesDBEntities();
public ActionResult Index()
{
return View(_db.MovieSet.ToList());
}
public ActionResult Create()
{
return View();
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create([Bind(Exclude = "Id")] Movie movieToCreate)
{
// Validate
if (!ModelState.IsValid)
return View();
// Add to database
try
{
_db.AddToMovieSet(movieToCreate);
_db.SaveChanges();
return RedirectToAction("Index");
}
catch
{
return View();
}
}
}
}
Třída domácího kontroleru ve výpisu 1 obsahuje dvě akce Create(). První akce zobrazí formulář HTML pro vytvoření nového filmu. Druhá akce Create() provede skutečné vložení nového filmu do databáze. Druhá akce Create() se vyvolá, když se formulář zobrazený první akcí Create() odešle na server.
Všimněte si, že druhá akce Create() obsahuje následující řádky kódu:
// Validate
if (!ModelState.IsValid)
return View();
IsValid Vlastnost vrátí false, pokud dojde k chybě ověření. V takovém případě se znovu zobrazí zobrazení Vytvořit, které obsahuje formulář HTML pro vytvoření videa.
Vytvoření částečné třídy
Třída Movie je generována rozhraním Entity Framework. Pokud v okně Průzkumník řešení rozbalíte soubor MoviesDBModel.edmx a otevřete MovieDBModel.Designer, uvidíte kód třídy Movie. cs v Editoru kódu (viz Obrázek 2).
Obrázek 02: Kód entity Film (kliknutím zobrazíte obrázek v plné velikosti)
Třída Movie je částečná třída. To znamená, že můžeme přidat další částečnou třídu se stejným názvem, abychom rozšířili funkčnost třídy Movie. Do nové částečné třídy přidáme naši logiku ověřování.
Přidejte třídu ve výpisu 2 do složky Modely.
Výpis 2 – Models\Movie.cs
using System.Collections.Generic;
using System.ComponentModel;
namespace MvcApplication1.Models
{
public partial class Movie
{
}
}
Všimněte si, že třída ve výpisu 2 obsahuje částečný modifikátor. Všechny metody nebo vlastnosti, které přidáte do této třídy, se stanou součástí třídy Movie vygenerované rozhraním Entity Framework.
Přidání částečných metod OnChanging a OnChanged
Když Entity Framework generuje třídu entity, Entity Framework přidá do třídy automaticky částečné metody. Entity Framework generuje OnChanging a OnChanged částečné metody, které odpovídají každé vlastnosti třídy.
V případě třídy Movie vytvoří Entity Framework následující metody:
- OnIdChanging
- OnIdChanged
- OnTitleChanging
- OnTitleChanged
- OnDirectorChanging
- OnDirectorChanged
- OnDateReleasedChanging
- OnDateReleasedChanged
OnChanging Metoda je volána těsně před odpovídající vlastnost je změněna. OnChanged Metoda je volána hned po změně vlastnosti.
Tyto částečné metody můžete využít k přidání ověřovací logiky do třídy Movie. Aktualizace třídy Movie ve výpisu 3 ověřuje, že vlastnosti Title a Director jsou přiřazeny neprázdné hodnoty.
Poznámka
Částečná metoda je metoda definovaná ve třídě, kterou nemusíte implementovat. Pokud neimplementujete částečnou metodu, kompilátor odebere podpis metody a všechna volání metody, takže s částečnou metodou nejsou spojené žádné náklady za běh. V editoru Visual Studio Code můžete přidat částečnou metodu zadáním klíčového slova partial následovaným mezerou pro zobrazení seznamu částečných hodnot, které se mají implementovat.
Výpis 3 – Models\Movie.cs
using System.Collections.Generic;
using System.ComponentModel;
namespace MvcApplication1.Models
{
public partial class Movie : IDataErrorInfo
{
private Dictionary<string, string> _errors = new Dictionary<string, string>();
partial void OnTitleChanging(string value)
{
if (value.Trim().Length == 0)
_errors.Add("Title", "Title is required.");
}
partial void OnDirectorChanging(string value)
{
if (value.Trim().Length == 0)
_errors.Add("Director", "Director is required.");
}
}
}
Pokud se například pokusíte přiřadit prázdný řetězec k title vlastnost, pak je přiřazena chybová zpráva slovníku s názvem _errors.
V tomto okamžiku se ve skutečnosti nic nestane, když přiřadíte prázdný řetězec k Title vlastnost a do privátního _errors pole je přidána chyba. Potřebujeme implementovat rozhraní IDataErrorInfo, aby se tyto chyby ověřování vystavily ASP.NET architektuře MVC.
Implementace rozhraní IDataErrorInfo
Rozhraní IDataErrorInfo je součástí rozhraní .NET Od první verze. Toto rozhraní je velmi jednoduché rozhraní:
public interface IDataErrorInfo
{
string this[string columnName] { get; }
string Error { get; }
}
Pokud třída implementuje rozhraní IDataErrorInfo, rozhraní ASP.NET MVC použije toto rozhraní při vytváření instance třídy . Například akce Vytvořit() domácího ovladače přijímá instanci třídy Movie:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create([Bind(Exclude = "Id")] Movie movieToCreate)
{
// Validate
if (!ModelState.IsValid)
return View();
// Add to database
try
{
_db.AddToMovieSet(movieToCreate);
_db.SaveChanges();
return RedirectToAction("Index");
}
catch
{
return View();
}
}
Rozhraní ASP.NET MVC vytvoří instanci Video předanou akci Create() pomocí pořadače modelu (DefaultModelBinder). Pořadač modelu je zodpovědný za vytvoření instance objektu Movie vazbou polí formuláře HTML na instanci objektu Movie.
DefaultModelBinder zjistí, zda třída implementuje rozhraní IDataErrorInfo. Pokud třída implementuje toto rozhraní, vazač modelu vyvolá indexer IDataErrorInfo.this pro každou vlastnost třídy. Pokud indexer vrátí chybovou zprávu, přidá pořadač modelu tuto chybovou zprávu do stavu modelu automaticky.
DefaultModelBinder také kontroluje vlastnost IDataErrorInfo.Error. Tato vlastnost je určena k reprezentaci chyb ověřování, které nejsou specifické pro vlastnost spojené s třídou . Můžete například chtít vynutit ověřovací pravidlo, které závisí na hodnotách více vlastností třídy Movie. V takovém případě byste vrátili chybu ověření z vlastnosti Error.
Aktualizovaná třída Movie ve výpisu 4 implementuje rozhraní IDataErrorInfo.
Výpis 4 – Models\Movie.cs (implementuje IDataErrorInfo)
using System.Collections.Generic;
using System.ComponentModel;
namespace MvcApplication1.Models
{
public partial class Movie : IDataErrorInfo
{
private Dictionary<string, string> _errors = new Dictionary<string, string>();
partial void OnTitleChanging(string value)
{
if (value.Trim().Length == 0)
_errors.Add("Title", "Title is required.");
}
partial void OnDirectorChanging(string value)
{
if (value.Trim().Length == 0)
_errors.Add("Director", "Director is required.");
}
#region IDataErrorInfo Members
public string Error
{
get
{
return string.Empty;
}
}
public string this[string columnName]
{
get
{
if (_errors.ContainsKey(columnName))
return _errors[columnName];
return string.Empty;
}
}
#endregion
}
}
Ve výpisu 4 vlastnost indexeru zkontroluje kolekci _errors a zjistí, jestli obsahuje klíč, který odpovídá názvu vlastnosti předané indexeru. Pokud k vlastnosti není přidružena žádná chyba ověřování, vrátí se prázdný řetězec.
Abyste mohli použít upravenou třídu Movie, není nutné nijak upravovat řadič Home. Stránka zobrazená na obrázku 3 znázorňuje, co se stane, když není pro pole formuláře Název nebo Ředitel zadána žádná hodnota.
Obrázek 03: Formulář s chybějícími hodnotami (kliknutím zobrazíte obrázek v plné velikosti)
Všimněte si, že hodnota DateReleased se ověřuje automaticky. Vzhledem k tomu, DateReleased vlastnost nepřijímá hodnoty NULL, DefaultModelBinder generuje chybu ověření pro tuto vlastnost automaticky, pokud nemá hodnotu. Pokud chcete upravit chybovou zprávu pro vlastnost DateReleased, musíte vytvořit vlastní pořadač modelu.
Souhrn
V tomto kurzu jste zjistili, jak pomocí rozhraní IDataErrorInfo generovat chybové zprávy ověřování. Nejprve jsme vytvořili částečnou třídu Movie, která rozšiřuje funkce částečné třídy Movie vygenerované rozhraním Entity Framework. Dále jsme přidali logiku ověřování do částečných metod třídy Movie OnTitleChanging() a OnDirectorChanging(). Nakonec jsme implementovali rozhraní IDataErrorInfo, abychom tyto ověřovací zprávy zpřístupnili rozhraní ASP.NET MVC.