Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
von Stephen Walther
Stephen Walther zeigt Ihnen, wie Sie benutzerdefinierte Validierungsfehlermeldungen anzeigen, indem Sie die IDataErrorInfo-Schnittstelle in einer Modellklasse implementieren.
Das Ziel dieses Tutorials besteht darin, einen Ansatz zum Durchführen der Validierung in einer ASP.NET MVC-Anwendung zu erläutern. Sie erfahren, wie Sie verhindern können, dass jemand ein HTML-Formular übermittelt, ohne Werte für erforderliche Formularfelder bereitzustellen. In diesem Tutorial erfahren Sie, wie Sie die Validierung mithilfe der IErrorDataInfo-Schnittstelle durchführen.
Annahmen
In diesem Tutorial verwende ich die MoviesDB-Datenbank und die Movies-Datenbanktabelle. Diese Tabelle weist die folgenden Spalten auf:
| Spaltenname | Datentyp | NULL-Werte zulassen |
|---|---|---|
| Id | Int | False |
| Titel | Nvarchar(100) | False |
| Regisseur | Nvarchar(100) | False |
| DateReleased | Datetime | False |
In diesem Tutorial verwende ich microsoft Entity Framework, um meine Datenbankmodellklassen zu generieren. Die vom Entity Framework generierte Movie-Klasse wird in Abbildung 1 angezeigt.
Abbildung 01: Die Movie-Entität(Klicken Sie, um das Bild in voller Größe anzuzeigen)
Hinweis
Weitere Informationen zur Verwendung von Entity Framework zum Generieren Ihrer Datenbankmodellklassen finden Sie in meinem Tutorial zum Erstellen von Modellklassen mit Entity Framework.
Die Controllerklasse
Wir verwenden den Home-Controller, um Filme aufzulisten und neue Filme zu erstellen. Der Code für diese Klasse ist in Listing 1 enthalten.
Eintrag 1: Controller\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();
}
}
}
}
Die Home-Controllerklasse in Listing 1 enthält zwei Create()-Aktionen. Die erste Aktion zeigt das HTML-Formular zum Erstellen eines neuen Films an. Die zweite Create()-Aktion führt den tatsächlichen Einfügevorgang des neuen Films in die Datenbank aus. Die zweite Create()-Aktion wird aufgerufen, wenn das von der ersten Create()-Aktion angezeigte Formular an den Server übermittelt wird.
Beachten Sie, dass die zweite Create()-Aktion die folgenden Codezeilen enthält:
// Validate
if (!ModelState.IsValid)
return View();
Die IsValid-Eigenschaft gibt false zurück, wenn ein Validierungsfehler vorliegt. In diesem Fall wird die Create-Ansicht, die das HTML-Formular zum Erstellen eines Films enthält, erneut angezeigt.
Erstellen einer partiellen Klasse
Die Movie-Klasse wird vom Entity Framework generiert. Sie können den Code für die Movie-Klasse sehen, wenn Sie die Datei MoviesDBModel.edmx im Projektmappen-Explorer Fenster erweitern und die MoviesDBModel.Designer öffnen. cs-Datei im Code-Editor (siehe Abbildung 2).
Abbildung 02: Der Code für die Movie-Entität(Klicken Sie, um das bild in voller Größe anzuzeigen)
Die Movie-Klasse ist eine partielle Klasse. Das bedeutet, dass wir eine weitere partielle Klasse mit demselben Namen hinzufügen können, um die Funktionalität der Movie-Klasse zu erweitern. Wir fügen die Validierungslogik der neuen partiellen Klasse hinzu.
Fügen Sie die Klasse in Listing 2 zum Ordner Models hinzu.
Eintrag 2: Models\Movie.cs
using System.Collections.Generic;
using System.ComponentModel;
namespace MvcApplication1.Models
{
public partial class Movie
{
}
}
Beachten Sie, dass die Klasse in Listing 2 den partiellen Modifizierer enthält. Alle Methoden oder Eigenschaften, die Sie dieser Klasse hinzufügen, werden Teil der Movie-Klasse, die vom Entity Framework generiert wird.
Hinzufügen von OnChanging- und OnChanged-Partiellen Methoden
Wenn Entity Framework eine Entitätsklasse generiert, fügt das Entity Framework der Klasse automatisch Partielle Methoden hinzu. Das Entity Framework generiert partielle OnChanging- und OnChanged-Methoden, die den einzelnen Eigenschaften der -Klasse entsprechen.
Im Fall der Movie-Klasse erstellt das Entity Framework die folgenden Methoden:
- OnIdChanging
- OnIdChanged
- OnTitleChanging
- OnTitleChanged
- OnDirectorChanging
- OnDirectorChanged
- OnDateReleasedChanging
- OnDateReleasedChanged
Die OnChanging-Methode wird direkt aufgerufen, bevor die entsprechende Eigenschaft geändert wird. Die OnChanged-Methode wird direkt aufgerufen, nachdem die Eigenschaft geändert wurde.
Sie können diese partiellen Methoden nutzen, um der Movie-Klasse Validierungslogik hinzuzufügen. Die Movie-Klasse aktualisieren in Listing 3 überprüft, ob die Title- und Director-Eigenschaften nicht erlösende Werte zugewiesen sind.
Hinweis
Eine partielle Methode ist eine Methode, die in einer Klasse definiert ist, die Sie nicht implementieren müssen. Wenn Sie keine partielle Methode implementieren, entfernt der Compiler die Methodensignatur und alle Aufrufe der Methode, sodass der partiellen Methode keine Laufzeitkosten entstehen. Im Visual Studio Code-Editor können Sie eine partielle Methode hinzufügen, indem Sie die Schlüsselwort (keyword) partielle und anschließend ein Leerzeichen eingeben, um eine Liste der zu implementierenden Partien anzuzeigen.
Eintrag 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.");
}
}
}
Wenn Sie beispielsweise versuchen, der Title-Eigenschaft eine leere Zeichenfolge zuzuweisen, wird einem Wörterbuch mit dem Namen _errors eine Fehlermeldung zugewiesen.
An diesem Punkt geschieht nichts, wenn Sie der Title-Eigenschaft eine leere Zeichenfolge zuweisen und dem Feld private _errors ein Fehler hinzugefügt wird. Wir müssen die IDataErrorInfo-Schnittstelle implementieren, um diese Überprüfungsfehler für das ASP.NET MVC-Framework verfügbar zu machen.
Implementieren der IDataErrorInfo-Schnittstelle
Die IDataErrorInfo-Schnittstelle ist seit der ersten Version Teil des .NET-Frameworks. Diese Schnittstelle ist eine sehr einfache Schnittstelle:
public interface IDataErrorInfo
{
string this[string columnName] { get; }
string Error { get; }
}
Wenn eine Klasse die IDataErrorInfo-Schnittstelle implementiert, verwendet das ASP.NET MVC-Framework diese Schnittstelle beim Erstellen eines instance der -Klasse. Die Aktion Create() des Homecontrollers akzeptiert beispielsweise eine instance der Movie-Klasse:
[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();
}
}
Das ASP.NET MVC-Framework erstellt die instance des Films, der an die Create()-Aktion übergeben wird, mithilfe eines Modellbinders (DefaultModelBinder). Der Modellbinder ist für das Erstellen einer instance des Movie-Objekts verantwortlich, indem die HTML-Formularfelder an eine instance des Movie-Objekts gebunden werden.
DefaultModelBinder erkennt, ob eine Klasse die IDataErrorInfo-Schnittstelle implementiert oder nicht. Wenn eine Klasse diese Schnittstelle implementiert, ruft der Modellbinder den Indexer IDataErrorInfo.this für jede Eigenschaft der Klasse auf. Wenn der Indexer eine Fehlermeldung zurückgibt, fügt der Modellbinder diese Fehlermeldung automatisch zum Modellzustand hinzu.
Der DefaultModelBinder überprüft auch die IDataErrorInfo.Error-Eigenschaft. Diese Eigenschaft soll nicht eigenschaftsspezifische Validierungsfehler darstellen, die der Klasse zugeordnet sind. Sie können beispielsweise eine Validierungsregel erzwingen, die von den Werten mehrerer Eigenschaften der Movie-Klasse abhängt. In diesem Fall würden Sie einen Überprüfungsfehler von der Error-Eigenschaft zurückgeben.
Die aktualisierte Movie-Klasse in Listing 4 implementiert die IDataErrorInfo-Schnittstelle.
Listing 4 – Models\Movie.cs (implementiert 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
}
}
In Listing 4 überprüft die Indexer-Eigenschaft die _errors Auflistung, um festzustellen, ob sie einen Schlüssel enthält, der dem an den Indexer übergebenen Eigenschaftsnamen entspricht. Wenn der -Eigenschaft kein Validierungsfehler zugeordnet ist, wird eine leere Zeichenfolge zurückgegeben.
Sie müssen den Home-Controller in keiner Weise ändern, um die geänderte Movie-Klasse zu verwenden. Die in Abbildung 3 angezeigte Seite veranschaulicht, was geschieht, wenn kein Wert für die Felder "Titel" oder "Direktor" eingegeben wird.
Abbildung 03: Formular mit fehlenden Werten (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)
Beachten Sie, dass der DateReleased-Wert automatisch überprüft wird. Da die DateReleased-Eigenschaft keine NULL-Werte akzeptiert, generiert defaultModelBinder automatisch einen Validierungsfehler für diese Eigenschaft, wenn sie keinen Wert aufweist. Wenn Sie die Fehlermeldung für die DateReleased-Eigenschaft ändern möchten, müssen Sie eine benutzerdefinierte Modellbindung erstellen.
Zusammenfassung
In diesem Tutorial haben Sie gelernt, wie Sie die IDataErrorInfo-Schnittstelle verwenden, um Validierungsfehlermeldungen zu generieren. Zunächst haben wir eine partielle Movie-Klasse erstellt, die die Funktionalität der teilweisen Movie-Klasse erweitert, die vom Entity Framework generiert wird. Als Nächstes haben wir validierungslogik zu den partiellen Methoden der Movie-Klasse OnTitleChanging() und OnDirectorChanging() hinzugefügt. Schließlich haben wir die IDataErrorInfo-Schnittstelle implementiert, um diese Validierungsmeldungen für das ASP.NET MVC-Framework verfügbar zu machen.