Validierung

Validierung bezeichnet grundsätzlich die Überprüfung von Daten (i.A. innerhalb eines Geschäftsprozesses) auf fachliche Korrektheit durch die automatische Anwendung von spezifizierten Validierungsbedingungen. Das Grundkonzept der Validierung besagt, dass letzten Endes diese in der Domänenlogik erfolgen sollte, die in den Ländern / Provinzen implementiert ist. Die Validierung ist in Form von Services gekapselt und i.A. in deren Schnittstellen-Design nach außen gelegt. Sie kann vor der eigentlichen Ausführung geprüft werden (frühe Validierung) oder während der eigentlichen Ausführung (späte Validierung), die im Fehlerfall zu Ausnahmen führt. Die Validierung immer in Benutzeroberflächen durch Services durchzuführen, ist allerdings aus Nutzersicht nicht immer vorteilhaft, da das Antwortverhalten häufig nicht den Anforderungen entspricht. Das heißt, dass beispielsweise im Falle des Editierens von Eingabefeldern, Validierung zusätzlich und redundant in der UI codiert und zur Laufzeit ausgeführt wird und somit ein besseres Nutzungserlebnis erzielt wird.

Validierung in Benutzeroberfläche

In Schleupen.CS 3.0-Benutzeroberflächen wird die Validierung dazu verwendet, Benutzereingaben auf fachliche Korrektheit zu überprüfen, bevor sie zur weiteren Bearbeitung an Services weitergegeben werden. Wenn die Eingabevalidierung keine validen Eingaben mehr anzeigt, greift die Validierung der Applikationslogik in den Services, die sich in einer anderen Schicht befindet.

Lokale Validierung: Eingabefeldvalidierung

Bei der Eingabefeldvalidierung werden die vom Benutzer in jeweils ein bestimmtes Eingabe-Control der Benutzeroberfläche eingegebenen Werte überprüft. Die Validierungsbedingungen können die Werte selber prüfen und im Zusammenspiel mit Werten anderer Eingabe-Controls im gleichen DialogStep definiert werden.

Die Eingabefeldvalidierung wird jeweils in dem Moment ausgelöst, in dem der Eingabefokus der Benutzeroberfläche das Control verlässt.

Eine fehlgeschlagene Eingabefeldvalidierung erzeugt stets eine oder mehrere Validierungsmeldungen, die unmittelbar am auslösenden Eingabe-Control angezeigt werden. Bei Fehlern in einer Eingabefeldvalidierung soll das Weitergehen aus dem aktuellen Dialogschritt zum nächsten Schritt verhindert werden.

Zum Anschluss der Eingabefeldvalidierung werden sogenannte Validatoren verwendet. Hierzu können vorgefertigte oder selber definierte Validatoren angebunden werden. U.a. folgende Validatoren können verwendet werden:

  • Contains - Prüft, ob eine Aufzählung den angegebenen Wert enthält oder ob ein Text den angegebenen Textbestandteil enthält. Gegenstück zu In. Anwendbar auf Aufzählungen und Texte (IEnumerable<T> und string).
  • In - Prüft, ob der Wert Teil der angegebenen Aufzählung ist. Gegenstück zu Contains. Anwendbar auf beliebige Typen.
  • Required - Markiert eine Eigenschaft als Pflichtangabe. Prüft, ob ein Wert eingegeben wurde (bei Texten mindestens ein Zeichen). Anwendbar auf beliebige Typen.
  • NotEmpty - Prüft ob eine Aufzählung Elemente enthält oder ein Text Zeichen enthält. Anwendbar auf IEnumerable<Typ> und string.
  • GreaterThan - Prüft, ob der Wert größer als der angegebene andere Wert ist. Anwendbar auf vergleichbare Typen, die IComparable implementieren und Nullable ValueTypes.
  • LessThan - Analog zu GreaterThan.
  • Satisfies - Prüft den Wert mit einem beliebig programmierbaren Validator (CustomValidator). Der CustomValidator erhält Zugriff auf das komplette ViewModel. Ist der Validator für einen Parameter eines Dialogschrittes formuliert, hat der CustomValidator Zugriff auf die gesamten Daten des Dialogschritts.
  • InstanceValidator - Beliebig programmierbare Prüfungen einer kompletten Instanz eines ViewModels oder Dialogschritts, die nach jeder Datenänderung ausgeführt werden. Aus Performance-Gründen sollten Prüfungen mit potentiell langer Laufzeit (>= 100ms) nicht in einem InstanceValidator, sondern ausschließlich im InstanceCompletionValidator angelegt werden.

Validierung und ViewModel können in der Beschreibung des DialogSteps zusammengebunden werden. Das folgende Beispiel zeigt exemplarisch den Anschluss des Validators NotEmpty.

public class BuchViewModel : ViewModel
{
    public BuchViewModel()
    {
        UseValidatorOf(typeof(BuchViewModelValidator));
    }   
    
    // ... Property Definitionen ...
}
public class BuchViewModelValidator : FluentViewModelValidator<BuchViewModel>
{
    public BuchViewModelValidator()
    {
        RuleFor(buch => buch.Titel).NotEmpty().WithMessage("{DisplayName} ist eine Pflichtangabe.");
    }
}

Die Validierung selber wird im PresentationServer ausgeführt.

Lokale und schichtenübegreifende DialogStep-Validierung 

Bei der DialogStep-Validierung werden übergreifende Validierungsbedingungen überprüft, die sich nicht einem einzelnen Eingabe-Control zuordnen lassen, sondern über den gesamten Datenkontext des jeweiligen Dialogschritts prüfen.

Die DialogStep-Validierung wird jeweils in dem Moment ausgelöst, in dem der Benutzer aus einem Dialogschritt in den nächsten Schritt des  DialogFlows weitergehen möchte. Eine fehlgeschlagene Dialogschrittvalidierung erzeugt stets eine oder mehrere Validierungsmeldungen, die in einem gesonderten Control im Dialogschritt angezeigt werden. Bei Fehlern in der Dialogschrittvalidierung soll das Weitergehen aus dem aktuellen Dialogschritt zum nächsten Dialogschritt oder das Beenden des DialogFlows verhindert werden.

Beim Verlassen des DialogSteps durch Betätigung des Buttons Weiter führt der Dialogschrittvalidierung zunächst die Eingabefeldvalidierung wie im vorherigen Abschnitt für sämtliche Controls durch. Nach der Eingabevalidierung werden die ViewModels validiert. Folgende Validierungen können hier zur Anwendung kommen (hier nur eine Auswahl):

  • InstanceCompletionValidator - Beliebig programmierbare Prüfungen einer kompletten Instanz eines ViewModels oder Dialogschritts, die beim Verlassen eines Dialogschritts im Rahmen der Vorwärts-Navigation ausgeführt werden. Diese Validierung findet also lokal statt.
  • SatisfiesWebservices - Validiert einen Wert oder ein ViewModel per Webservice mit einer Validate-Operation. Die Webservice-Validierung wird aus Performance-Gründen erst beim Verlassen des Dialogschritts im Rahmen einer Vorwärts-Navigation ausgeführt. Diese Validierung ist schichtenübergreifend.

Ob beim Verlassen des DialogSteps eine lokale Validierung des gesamten ViewModels oder die schichtenübergreifende Validierung per Service-Aufruf besser ist, kann man im Allgemeinen nicht beantworten. Dies ist ein Trade-Off zwischen der Verletzung des DRY-Prinzips, Performance, Aufwand usw.

Validierung und ViewModel werden in der Beschreibung des DialogSteps zusammengebunden. Das folgende Beispiel zeigt exemplarisch den Anschluss des Validators SatisfiesWebservices.

<?xml version="1.0" encoding="utf-16"?>
<DialogStep ... xmlns="urn://Schleupen.CS.PI.PR.DialogStep_2.1">
  <Properties>
    <Property Name="BuchModel" Type="BuchViewModel" ...>
      <Rule>
        <SatisfiesWebservice Operation="ValidateBuch" ... />
      </Rule>
    </Property>
  </Properties>
 ...
<DialogStep>

In der PresentationEngine ist es möglich, die Service-Validierung auch im ViewModel anzuschließen. Hiervon ist allerdings abzuraten, da ansonsten eine unerwünschte Kopplung von ViewModel zu Services erfolgen würde und auch im UI-Kontext ViewModel analog zu Domänenmodellen möglichst technologieneutral sein sollten.

Die folgende Abbildung zeigt die Schritte der Validierung durch die Domänenlogik im Service.

Die Anbindung der DialogStep-Validierung findet auf dem PresentationServer statt.

DialogFlow-Validierung

Zunächst betrachten wir die Validierung beim Übergang zwischen zwei Dialogschritten, aus denen ein DialogFlow bestehen möge: Bei der Stammdatenerfassung möchte man am Ende ein "Aggregate" haben, mit dem in unterschiedlichen Geschäftsprozessen weiter gearbeitet werden kann - d.h. das Aggregate soll nicht nur valide bezüglich Persistenz, sondern auch hinsichtlich der weiteren fachlichen Nutzung sein. Oftmals sind dies ein und dasselbe - konzeptionell hingegen nicht.

Normalerweise erfasst man zusammenhängende Daten eines "Aggregate" in einen Dialogschritt. Manchmal teilt sich die Erfassung auf und nach jedem Dialogschritt kann diese gespeichert werden. Im ersten Schritt eines solchen Ablaufs wird dann über einen Service mit einer Validate-Operation hinsichtlich der Persistierbarkeit validiert. Bei der Erfassung im nächsten Schritt werden Daten und Datenbeziehungen ergänzt, so dass dieses Aggegate dann gültig bzgl. der Nutzung in weiteren Kontexten ist. Beim Übergang zu einem nächsten Schritt wird jeweils das Validieren bzgl. anderer Kontexte geprüft. Gibt es Validierungsfehler, wird das Aggregate gespeichert, aber die Navigation zum nächsten Schritt wird nicht ausgeführt

Die folgende Abbildung zeigt ein Beispiel:

Bei der DialogFlow-Validierung werden übergreifende Validierungsbedingungen überprüft, die sich nicht einem einzelnen Eingabe-Control oder einem einzelnen Dialogschritt zuordnen lassen, sondern über den gesamten Datenkontext des Dialogablaufs definiert sind. Die Dialogablaufvalidierung wird jeweils in dem Moment ausgelöst, in dem der Benutzer den Dialogablauf abschließen will. Eine fehlgeschlagene Dialogablaufvalidierung erzeugt stets eine oder mehrere Validierungsmeldungen, die in einem gesonderten Control des aktuellen Dialogschritts oder auf einem eigenen Dialogschritt angezeigt werden. Bei Fehlern in der Dialogablaufvalidierung kann der Dialogablauf nicht erfolgreich abgeschlossen werden.

Der Ablauf der DialogFlow-Validierung umfasst folgende Schritte:

Validierung in Workflows

In Workflows wird keine spezifische Validierung codiert. Hier kommt die späte Validierung in den Services zur Anwendung.

Cookie Consent mit Real Cookie Banner