Deklarative Einschränkungen
Deklarative Einschränkungen stellen eine leistungsstarke Validierungsmethode für eine Aktivität und ihre Beziehungen zu anderen Aktivitäten bereit. Einschränkungen werden während des Erstellungsprozesses für eine Aktivität konfiguriert. Der Workflowhost kann jedoch zusätzliche Einschränkungen angeben. Dieses Thema bietet eine Übersicht darüber, wie mit deklarativen Einschränkungen Aktivitätsvalidierung bereitgestellt werden kann.
Verwendung deklarativer Einschränkungen
Eine Einschränkung ist eine Aktivität, die Validierungslogik enthält. Die Einschränkungsaktivität kann in Code oder in XAML erstellt werden. Nachdem eine Einschränkungsaktivität erstellt wurde, wird sie von Aktivitätsautoren der Constraints-Eigenschaft hinzugefügt, die validiert werden soll, oder die Autoren verwenden die Einschränkung, um zusätzliche Validierung mithilfe der AdditionalConstraints-Eigenschaft einer ValidationSettings-Instanz bereitzustellen. Die Validierungslogik kann aus einfachen Validierungen wie der Validierung der Metadaten einer Aktivität bestehen, sie kann jedoch auch eine Validierung ausführen, die die Beziehung der betreffenden Aktivität zum übergeordneten Element, den untergeordneten Elementen und den gleichgeordneten Aktivitäten berücksichtigt. Einschränkungen werden mit der Constraint<T>-Aktivität erstellt. Es werden mehrere zusätzliche Validierungsaktivitäten bereitgestellt, um die Erstellung von Validierungsfehlern und -warnungen zu unterstützen und Informationen zu verwandten Aktivitäten im Workflow zur Verfügung zu stellen.
AssertValidation und AddValidationError
Die AssertValidation-Aktivität wertet den Ausdruck aus, auf den von der Assertion-Eigenschaft verwiesen wird. Wenn der ausgewertete Ausdruck false
ergibt, wird ValidationResults ein Validierungsfehler oder eine Warnung hinzugefügt. Die Message-Eigenschaft beschreibt den Validierungsfehler, und die IsWarning-Eigenschaft gibt an, ob es sich dabei um einen Fehler oder eine Warnung handelt. Der Standardwert für IsWarning ist false
.
Im folgenden Beispiel wird eine Einschränkung deklariert, die eine Validierungswarnung zurückgibt, wenn der DisplayName der validierten Aktivität zwei Zeichen oder weniger umfasst. Der generische Typparameter, der für das Constraint<T>-Objekt verwendet wird, gibt den Typ der Aktivität an, die von der Einschränkung validiert wird. Diese Einschränkung verwendet das Activity-Objekt als generischen Typ. Mit ihr können alle Aktivitätstypen validiert werden.
public static Constraint ActivityDisplayNameIsNotSetWarning()
{
DelegateInArgument<Activity> element = new DelegateInArgument<Activity>();
return new Constraint<Activity>
{
Body = new ActivityAction<Activity, ValidationContext>
{
Argument1 = element,
Handler = new AssertValidation
{
IsWarning = true,
Assertion = new InArgument<bool>(env => (element.Get(env).DisplayName.Length > 2)),
Message = new InArgument<string>("It is a best practice to have a DisplayName of more than 2 characters."),
}
}
};
}
Um diese Einschränkung für eine Aktivität anzugeben, wird sie den Constraints der Aktivität hinzugefügt, wie im folgenden Beispielcode gezeigt.
public sealed class SampleActivity : CodeActivity
{
public SampleActivity()
{
base.Constraints.Add(ActivityDisplayNameIsNotSetWarning());
}
// Activity implementation omitted.
}
Diese Einschränkung kann der Host auch mithilfe von AdditionalConstraints für Aktivitäten in einem Workflow angegeben. Dieses Thema wird im nächsten Abschnitt behandelt.
Mit der AddValidationError-Aktivität wird ein Validierungsfehler oder eine Validierungswarnung generiert, ohne dass ein Ausdruck ausgewertet werden muss. Ihre Eigenschaften stimmen zum großen Teil mit denen des AssertValidation-Objekts überein, und die Aktivität kann zusammen mit den Flusssteuerungsaktivitäten einer Einschränkung wie der If-Aktivität verwendet werden.
Workflowbeziehungsaktivitäten
Es gibt mehrere Validierungsaktivitäten, die Informationen zu den anderen Aktivitäten im Workflow im Verhältnis zur validierten Aktivität bereitstellen. GetParentChain gibt eine Auflistung von Aktivitäten zurück, die alle Aktivitäten zwischen der aktuellen Aktivität und der Stammaktivität enthält. GetChildSubtree stellt eine Auflistung von Aktivitäten bereit, die die untergeordneten Aktivitäten in einem rekursiven Muster enthält, und GetWorkflowTree ruft alle Aktivitäten im Workflow ab.
Im folgenden Beispiel wird eine CreateState
-Aktivität definiert. Die CreateState
-Aktivität muss in einer CreateCountry
-Aktivität enthalten sein, und die GetParent
-Methode gibt eine Einschränkung zurück, die diese Anforderung durchsetzt. GetParent
verwendet die GetParentChain-Aktivität in Verbindung mit einer ForEach<T>-Aktivität, um die übergeordneten Aktivitäten der CreateState
-Aktivität zu überprüfen und zu ermitteln, ob die Anforderung erfüllt wurde.
public sealed class CreateState : CodeActivity
{
public CreateState()
{
base.Constraints.Add(CheckParent());
this.Cities = new List<Activity>();
}
public List<Activity> Cities { get; set; }
public string Name { get; set; }
static Constraint CheckParent()
{
DelegateInArgument<CreateState> element = new DelegateInArgument<CreateState>();
DelegateInArgument<ValidationContext> context = new DelegateInArgument<ValidationContext>();
Variable<bool> result = new Variable<bool>();
DelegateInArgument<Activity> parent = new DelegateInArgument<Activity>();
return new Constraint<CreateState>
{
Body = new ActivityAction<CreateState,ValidationContext>
{
Argument1 = element,
Argument2 = context,
Handler = new Sequence
{
Variables =
{
result
},
Activities =
{
new ForEach<Activity>
{
Values = new GetParentChain
{
ValidationContext = context
},
Body = new ActivityAction<Activity>
{
Argument = parent,
Handler = new If()
{
Condition = new InArgument<bool>((env) => object.Equals(parent.Get(env).GetType(),typeof(CreateCountry))),
Then = new Assign<bool>
{
Value = true,
To = result
}
}
}
},
new AssertValidation
{
Assertion = new InArgument<bool>(result),
Message = new InArgument<string> ("CreateState has to be inside a CreateCountry activity"),
}
}
}
}
};
}
protected override void Execute(CodeActivityContext context)
{
// not needed for the sample
}
}
Zusätzliche Einschränkungen
Workflowhostautoren können zusätzliche Validierungseinschränkungen für Aktivitäten in einem Workflow angeben, indem sie Einschränkungen erstellen und dem AdditionalConstraints-Wörterbuch einer ValidationSettings-Instanz hinzufügen. Jedes Element in AdditionalConstraints enthält den Typ der Aktivität, für den die Einschränkungen gültig sind, sowie eine Liste der zusätzlichen Einschränkungen für diesen Aktivitätstyp. Wenn die Validierung für den Workflow aufgerufen wird, wertet jede Aktivität des angegebenen Typs (einschließlich der abgeleiteten Klassen) die Einschränkungen aus. In diesem Beispiel wird die ActivityDisplayNameIsNotSetWarning
-Einschränkung aus dem vorherigen Abschnitt auf alle Aktivitäten in einem Workflow angewendet.
Activity wf = new Sequence
{
// Workflow Details Omitted.
};
ValidationSettings settings = new ValidationSettings()
{
AdditionalConstraints =
{
{typeof(Activity), new List<Constraint> {ActivityDisplayNameIsNotSetWarning()}},
}
};
// Validate the workflow.
ValidationResults results = ActivityValidationServices.Validate(wf, settings);
// Evaluate the results.
if (results.Errors.Count == 0 && results.Warnings.Count == 0)
{
Console.WriteLine("No warnings or errors");
}
else
{
foreach (ValidationError error in results.Errors)
{
Console.WriteLine("Error in " + error.Source.DisplayName + ": " + error.Message);
}
foreach (ValidationError warning in results.Warnings)
{
Console.WriteLine("Warning in " + warning.Source.DisplayName + ": " + warning.Message);
}
}
Wenn die OnlyUseAdditionalConstraints-Eigenschaft des ValidationSettings-Objekts true
ist, werden nur die angegebenen zusätzlichen Einschränkungen ausgewertet, nachdem die Validierung über den Aufruf von Validate aufgerufen wird. Dies kann hilfreich sein, wenn überprüft wird, ob Workflows über bestimmte Validierungskonfigurationen verfügen. Beachten Sie jedoch, dass beim Aufrufen des Workflows die im Workflow konfigurierte Validierungslogik ausgewertet wird und weitergegeben werden muss, damit der Workflow erfolgreich gestartet werden kann. Weitere Informationen zum Aufrufen der Überprüfung finden Sie unter Aufrufen der Aktivitätsvalidierung.