Think First Development

Erst denken, dann programmieren

Durchsuche Beiträge in ASP.NET MVC

Die Implementierung von Validierung ist ein leidiges Thema. Bei der Validierung muss man zwischen drei Arten des Validierungskontextes unterscheiden:

  • Validierung von atomaren Eigenschaften. Beispiel: Pflichtfelder.
  • Validierung eines einfachen Modells, bei dem sich die zu prüfenden Eigenschaften innerhalb einer Klasse befinden. Beispiel: Geburtstag liegt vor dem Todestag.
  • Validierung eines komplexen Modells bei dem mehrere Objekte oder Klassen involviert sind. Beispiel: Die Kombination Vorname und Nachname muss eindeutig sein.

Das ASP.NET MVC2 Framework unterstützt die Validierung von Eigenschaften mittels DataAnnotations. Mehr dazu in einem vorherigen Blogeintrag. Der Vorteil dieser DataAnnotations liegt in der Wiederverwendbarkeit der Attribute bei verschiedenen Eigenschaften.

Mit der Version 3 des ASP.NET MVC Frameworks ist eine Modellvalidierung in Kombination mit der Eigenschaftsvalidierung möglich. Da im Gegensatz zur Eigenschaftsvalidierung ist die Modellvalidierung nicht wiederwendbar und wird daher direkt in das Modell implementiert. Dazu muss die Klasse die Schnittstelle “IValidatableObject” mit der Methode “Validate” implementieren. Der Rückgabewert ist ein IEnumerable<of ValidationResults>, die sowohl Modellfehler als auch Eigenschaftsfehler enthält. Das kleine Beispiel zeigt die Verwendung der Modellvalidierung, sowohl für eigenschaftsbezogene Fehler, als auch für allgemeine Modellfehler.

image

image

Dass die clientseitige Validierung vor der serverseitigen ausgeführt wird ist logisch. Das bedeutet, das standardmäßig nur die Validierungen der integrierten DataAnnotations durchgeführt wird.

Überraschend ist allerdings folgendes serverseitiges Verhalten, wenn die clientseitige Validierung nicht aktiviert ist: Die DataAnnotation-Validierung werden vor der Modellvalidierung durchgeführt. Hat die DataAnnotation-Validierung mindestens einen Fehler, wird die Modellvalidierung nicht durchgeführt. Das Verhalten hat gewünschte oder unerwünschte Nebenwirkungen. Die serverseitige Validierung wird bei Fehlern mehrmals durchlaufen, einmal für die DataAnnotationen und einmal für die Modellvalidierung. Der klare Vorteil liegt hier, wenn die Modellvalidierung komplexe Datenbankabfragen macht, da diese bei einfachen Modellfehlern nicht durchgeführt werden. Im Gegenzug ist es nicht möglich, Validierungsfehler von DataAnnotations und Modellvalidierung gleichzeitig anzuzeigen.

Die Modellvalidierung ist ein wichtiger Schritt, um die Validierung zu vereinheitlichen. Damit werden individuelle Implementierungen und Konzepte durch ein gemeinsames Konzept abgelöst.

Das Ermitteln einer View folgt dem Mechanismus “Von Spezialisierten zum Generalisierten”. Das folgende Bild zeigt die Reihenfolge in Kombination mit Areas.

Diese Reihenfolge gilt für den Lookup von sowohl Views als auch Partial Views. Das gilt für jedes (!) Lookup, auch innerhalb von Views (z.B. bei Html.RenderPartial()). Diesen Umstand kann man sich zu nutze machen um Polymorphie abzubilden. Gegeben ist folgendes Modell.

image

Damit bietet es sich an, eine Shared View für “Contact” zu erstellen. Aber was passiert mit den Eigenschaften, die nur in den spezialisierten Klassen “Person” und “Company” existieren. Die ContactView ist für die “Contact” Basisklasse typisiert.

An dieser Stelle hilft die Lookup-Reihenfolge. Benutzt man in der Shared View ein RenderPartial(), kann man spezialisierten Views in den Controllern definieren.

image

Das Ergebnis ist, dass im CompanyController zusätzlich die CompanyView “SpecialView” gerendert wird und im PersonController die PersonView “SpezialView”. Es wird also automatisch zuerst in den Views für den Controller nachgeschaut. Einziges Problem mit RenderPartial() ist eine Exception, wenn in einem dritten Controller die “SpezialView” nicht implementiert ist, die ContactView aber gerendert wird.

image  image

Zu bemerken ist abschließend noch, dass die SpezialViews auf die spezialisierten Klassen typisiert ist, also Person bzw. Company. Das MVC2 Framework übernimmt (vereinfacht dargestellt) die Umwandlung von Contact in Person bzw. Company.

Powered by WordPress Web Design by SRS Solutions © 2010 Think First Development Design by SRS Solutions