Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
I vincoli dichiarativi forniscono un metodo potente di convalida per un'attività e le relative relazioni con altre attività. I vincoli vengono configurati per un'attività durante il processo di creazione, ma è anche possibile specificare vincoli aggiuntivi dall'host del flusso di lavoro. In questo argomento viene fornita una panoramica dell'uso di vincoli dichiarativi per fornire la convalida delle attività.
Uso di vincoli dichiarativi
Un vincolo è un'attività che contiene la logica di convalida. Questa attività di vincolo può essere creata nel codice o in XAML. Dopo che è stato creato un vincolo attività, gli autori di attività aggiungono questo vincolo alla proprietà Constraints dell'attività da convalidare oppure usano il vincolo per fornire una convalida aggiuntiva utilizzando la proprietà AdditionalConstraints di un'istanza ValidationSettings. La logica di convalida può essere costituita da semplici convalide, ad esempio la convalida dei metadati di un'attività, ma può anche eseguire la convalida che tiene conto della relazione dell'attività corrente con le attività padre, figlio e di pari livello. I vincoli vengono creati usando l'attività Constraint<T> e vengono fornite diverse attività di convalida aggiuntive per facilitare la creazione di errori e avvisi di convalida e per fornire informazioni sulle attività correlate nel flusso di lavoro.
AssertValidation e AddValidationError
L'attività AssertValidation valuta l'espressione a cui fa riferimento la proprietà Assertion e se l'espressione restituisce false, viene aggiunto un errore di convalida o un avviso all'oggetto ValidationResults. La Message proprietà descrive l'errore di convalida e la IsWarning proprietà indica se l'errore di convalida è un errore o un avviso. Il valore predefinito per IsWarning è false.
Nell'esempio seguente viene dichiarato un vincolo che restituisce un avviso di convalida se l'oggetto DisplayName dell'attività convalidata è di due caratteri o minore di lunghezza. Il parametro di tipo generico utilizzato per Constraint<T> specifica il tipo di attività convalidato dal vincolo. Questo vincolo usa Activity come tipo generico e può essere usato per convalidare tutti i tipi di attività.
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."),
}
}
};
}
Per specificare questo vincolo per un'attività, viene aggiunto all'oggetto Constraints dell'attività, come illustrato nel codice di esempio seguente.
public sealed class SampleActivity : CodeActivity
{
public SampleActivity()
{
base.Constraints.Add(ActivityDisplayNameIsNotSetWarning());
}
// Activity implementation omitted.
}
L'host può anche specificare questo vincolo per le attività in un flusso di lavoro usando AdditionalConstraints, illustrato nella sezione successiva.
L'attività AddValidationError viene usata per generare un errore di convalida o un avviso senza richiedere la valutazione di un'espressione. Le sue proprietà sono simili a AssertValidation e possono essere utilizzate insieme alle attività di controllo del flusso di un vincolo, come l'attività If.
Attività di relazione del flusso di lavoro
Sono disponibili diverse attività di convalida che forniscono informazioni sulle altre attività nel flusso di lavoro in relazione all'attività da convalidare. GetParentChain restituisce una raccolta di attività che contiene tutte le attività tra l'attività corrente e l'attività radice. GetChildSubtree fornisce una raccolta di attività che contiene le attività figlio in un modello ricorsivo e GetWorkflowTree ottiene tutte le attività nel flusso di lavoro.
Nell'esempio seguente viene definita un'attività CreateState . L'attività CreateState deve essere contenuta all'interno di un'attività CreateCountry e il GetParent metodo restituisce un vincolo che applica questo requisito.
GetParent utilizza l'attività GetParentChain in congiunzione con un'attività ForEach<T> per ispezionare le attività padre dell'attività CreateState e determinare se il requisito è soddisfatto.
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
}
}
Vincoli aggiuntivi
Gli autori dell'host del flusso di lavoro possono specificare vincoli di convalida aggiuntivi per le attività in un flusso di lavoro creando vincoli e aggiungendoli al dizionario di un'istanza AdditionalConstraintsValidationSettings. Ogni elemento di AdditionalConstraints contiene il tipo di attività per cui si applicano i vincoli e un elenco dei vincoli aggiuntivi per quel tipo di attività. Quando viene richiamata la convalida per il flusso di lavoro, ogni attività del tipo specificato, incluse le classi derivate, valuta i vincoli. In questo esempio il ActivityDisplayNameIsNotSetWarning vincolo della sezione precedente viene applicato a tutte le attività di un flusso di lavoro.
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);
}
}
Se la OnlyUseAdditionalConstraints proprietà di ValidationSettings è true, solo i vincoli aggiuntivi specificati vengono valutati quando la convalida viene richiamata chiamando Validate. Ciò può essere utile per controllare i flussi di lavoro per configurazioni di convalida specifiche. Si noti tuttavia che quando viene richiamato il flusso di lavoro, la logica di convalida configurata nel flusso di lavoro viene valutata e deve passare affinché il flusso di lavoro inizi correttamente. Per altre informazioni sulla chiamata della convalida, vedere Richiamo della convalida dell'attività.