Appel de la validation d'activité
Cette rubrique s'applique à Windows Workflow Foundation 4.
La validation d'activité offre une méthode d'identification et de signalisation des erreurs dans la configuration de toute activité, avant son exécution. La validation a lieu lorsque, dans le Concepteur de Workflow, un workflow est modifié et que l'ensemble des erreurs ou avertissements de validation sont affichés. La validation a également lieu au moment de l'exécution, lors de l'appel d'un flux de travail. Et si toute erreur de validation se produit, la logique de validation par défaut lève un objet InvalidWorkflowException. Windows Workflow Foundation (WF) fournit la classe ActivityValidationServices utilisable par les développeurs d'application de workflow et d'outillage pour valider explicitement une activité. Cette rubrique décrit comment utiliser la classe ActivityValidationServices pour valider une activité.
Utilisation de la classe ActivityValidationServices
La classe ActivityValidationServices compte deux surcharges Validate, utilisées pour appeler la logique de validation d'une activité. La première surcharge prend l'activité racine à valider et retourne une collection d'erreurs et avertissements de validation. Dans l'exemple suivant, une activité Add
personnalisée qui compte deux arguments requis est utilisée.
public sealed class Add : CodeActivity<int>
{
[RequiredArgument]
public InArgument<int> Operand1 { get; set; }
[RequiredArgument]
public InArgument<int> Operand2 { get; set; }
protected override int Execute(CodeActivityContext context)
{
return Operand1.Get(context) + Operand2.Get(context);
}
}
L'activité Add
est utilisée dans un objet Sequence, mais ses deux arguments requis ne sont pas liés, comme indiqué dans l'exemple suivant :
Variable<int> Operand1 = new Variable<int>{ Default = 10 };
Variable<int> Operand2 = new Variable<int>{ Default = 15 };
Variable<int> Result = new Variable<int>();
Activity wf = new Sequence
{
Variables = { Operand1, Operand2, Result },
Activities =
{
new Add(),
new WriteLine
{
Text = new InArgument<string>(env => "The result is " + Result.Get(env))
}
}
};
Ce workflow peut être validé en appelant la méthode Validate. La méthode Validate retourne une collection de l'ensemble des erreurs ou avertissements de validation contenus dans l'activité et tout enfant, comme indiqué dans l'exemple suivant :
ValidationResults results = ActivityValidationServices.Validate(wf);
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: {0}", error.Message);
}
foreach (ValidationError warning in results.Warnings)
{
Console.WriteLine("Warning: {0}", warning.Message);
}
}
Remarque : |
---|
Les auteurs d'activités personnalisés peuvent fournir la logique de validation dans la substitution CacheMetadata d'une activité. Toutes les exceptions levées à partir de CacheMetadata ne sont pas traitées comme des erreurs de validation. Ces exceptions échapperont à l'appel à Validate et doivent être gérées par l'appelant. |
Lorsque Validate est appelé sur cet exemple de workflow, deux erreurs de validation sont retournées.
Erreur : La valeur pour un argument d'activité 'Operand2' requis n'a pas été fournie.
Erreur : La valeur pour un argument d'activité 'Operand1' requis n'a pas été fournie.
Si ce workflow était appelé, un InvalidWorkflowException serait levé, comme indiqué dans l'exemple suivant :
try
{
WorkflowInvoker.Invoke(wf);
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
System.Activities.InvalidWorkflowException :
Les erreurs suivantes ont été rencontrées lors du traitement de l'arborescence du workflow :
'Add' : La valeur pour un argument d'activité 'Operand2' requis n'a pas été fournie.
'Add' : La valeur pour un argument d'activité 'Operand1' requis n'a pas été fournie.
Pour que cet exemple de workflow soit valide, les deux arguments requis de l'activité Add
doivent être liés. Dans l'exemple suivant, les deux arguments requis sont liés aux variables de flux de travail, tout comme la valeur de résultat. Dans cet exemple, l'argument Result est lié, ainsi que les deux arguments requis. L'argument Result ne doit pas forcément être lié et ne provoque pas d'erreur de validation s'il ne l'est pas. Il incombe à l'auteur du workflow de lier l'objet Result, si sa valeur est utilisée ailleurs dans le flux de travail.
new Add
{
Operand1 = Operand1,
Operand2 = Operand2,
Result = Result
}
Validation des arguments requis à l'activité racine
Si l'activité racine d'un flux de travail comporte des arguments, ceux-ci ne sont pas liés jusqu'à ce que le flux de travail soit appelé et que les paramètres soient passés à ce dernier. Ainsi, le flux de travail suivant passe la validation, mais une exception est levée si le flux de travail a été appelé sans passer les arguments requis, comme indiqué dans l'exemple suivant :
Activity wf = new Add();
ValidationResults results = ActivityValidationServices.Validate(wf);
// results has no errors or warnings, but when the workflow
// is invoked, an InvalidWorkflowException is thrown.
try
{
WorkflowInvoker.Invoke(wf);
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
System.ArgumentException: The root activity's argument settings are incorrect.
Either fix the workflow definition or supply input values to fix these errors:
'Add': Value for a required activity argument 'Operand2' was not supplied.
'Add': Value for a required activity argument 'Operand1' was not supplied.
Une fois les arguments appropriés passés, le flux de travail se termine correctement, comme indiqué dans l'exemple suivant :
Add wf = new Add();
ValidationResults results = ActivityValidationServices.Validate(wf);
// results has no errors or warnings, and the workflow completes
// successfully because the required arguments were passed.
try
{
Dictionary<string, object> wfparams = new Dictionary<string, object>
{
{ "Operand1", 10 },
{ "Operand2", 15 }
};
int result = WorkflowInvoker.Invoke(wf, wfparams);
Console.WriteLine("Result: {0}", result);
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
Remarque : |
---|
Dans cet exemple, l'activité racine a été déclarée comme activité Add plutôt qu'Activity comme dans l'exemple précédent. La méthode WorkflowInvoker.Invoke peut ainsi retourner un entier unique qui représente les résultats de l'activité Add , au lieu d'un dictionnaire d'arguments out. La variable wf aurait également pu être déclarée comme Activity<int> .
|
Lors de la validation d'arguments racines, il incombe à l'application hôte de vérifier que tous les arguments requis sont passés pendant l'appel du flux de travail.
Utilisation de ValidationSettings
Par défaut, toutes les activités de l'arborescence d'activité sont évaluées lors de l'appel de la validation par l'objet ActivityValidationServices. L'objet ValidationSettings vous permet de personnaliser la validation de plusieurs façons différentes en configurant ses trois propriétés. La propriété SingleLevel spécifie si le validateur doit parcourir l'arborescence d'activité entière ou uniquement appliquer la logique de validation à l'activité fournie. La valeur par défaut de cette valeur est false. La propriété AdditionalConstraints spécifie un mappage de contraintes supplémentaires, d'un type vers une liste de contraintes. Pour le type de base de chaque activité de l'arborescence en cours de validation, il existe une recherche dans la propriété AdditionalConstraints. En cas de détection d'une liste de contraintes correspondante, toutes les contraintes de la liste sont évaluées pour l'activité. La propriété OnlyUseAdditionalConstraints spécifie si le validateur doit évaluer toutes les contraintes ou seulement celles spécifiées dans la propriété AdditionalConstraints. La valeur par défaut est false. Grâce aux propriétés AdditionalConstraints et OnlyUseAdditionalConstraints, les auteurs hôtes de flux de travail peuvent ajouter une validation supplémentaire pour les flux de travail comme les contraintes de stratégie pour les outils tels que FxCop. Pour plus d'informations sur le sujet suivant les contraintes, consultez Contraintes déclaratives.
Pour utiliser l'objet ValidationSettings, configurez les propriétés de votre choix, puis passez-le dans l'appel à la méthode Validate. Dans cet exemple, un flux de travail, qui consiste en un objet Sequence avec une activité Add
personnalisée, est validé. L'activité Add
compte deux arguments requis.
public sealed class Add : CodeActivity<int>
{
[RequiredArgument]
public InArgument<int> Operand1 { get; set; }
[RequiredArgument]
public InArgument<int> Operand2 { get; set; }
protected override int Execute(CodeActivityContext context)
{
return Operand1.Get(context) + Operand2.Get(context);
}
}
L'activité Add
suivante est utilisée dans un objet Sequence, mais ses deux arguments requis ne sont pas liés.
Variable<int> Operand1 = new Variable<int> { Default = 10 };
Variable<int> Operand2 = new Variable<int> { Default = 15 };
Variable<int> Result = new Variable<int>();
Activity wf = new Sequence
{
Variables = { Operand1, Operand2, Result },
Activities =
{
new Add(),
new WriteLine
{
Text = new InArgument<string>(env => "The result is " + Result.Get(env))
}
}
};
Pour l'exemple suivant, la validation est effectuée avec la propriété SingleLevel définie sur true. Aussi seule l'activité Sequence racine est-elle validée.
ValidationSettings settings = new ValidationSettings
{
SingleLevel = true
};
ValidationResults results = ActivityValidationServices.Validate(wf, settings);
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: {0}", error.Message);
}
foreach (ValidationError warning in results.Warnings)
{
Console.WriteLine("Warning: {0}", warning.Message);
}
}
Ce code affiche la sortie suivante :
Aucun avertissement ni aucune erreur
Bien que l'activité Add
comporte des arguments requis non liés, la validation est réussie, car seule l'activité racine a été évaluée. Ce type de validation est utile pour valider uniquement des éléments particuliers d'une arborescence d'activité, par exemple pour valider, dans un concepteur, une modification de propriété d'une activité unique. Notez que si ce flux de travail devait être appelé, la validation complète configurée dans le flux de travail serait évaluée et un objet InvalidWorkflowException serait levé. Les objets ActivityValidationServices et ValidationSettings configurent uniquement la validation explicitement appelée par l'hôte, et non la validation qui a lieu lors de l'appel d'un flux de travail.