Vincoli dichiarativiDeclarative Constraints

I vincoli dichiarativi offrono un metodo potente di convalida per un'attività e le relative relazioni con altre attività.Declarative constraints provide a powerful method of validation for an activity and its relationships with other activities. I vincoli vengono configurati per un'attività durante il processo di creazione, ma vincoli aggiuntivi possono essere specificati anche dall'host del flusso di lavoro.Constraints are configured for an activity during the authoring process, but additional constraints can also be specified by the workflow host. In questo argomento viene fornita una panoramica sull'utilizzo di vincoli dichiarativi per la convalida delle attività.This topic provides an overview of using declarative constraints to provide activity validation.

Uso di vincoli dichiarativiUsing Declarative Constraints

Un vincolo è un'attività che contiene la logica di convalida.A constraint is an activity that contains validation logic. Questa attività del vincolo può essere creata nel codice o in XAML.This constraint activity can be authored in code or in XAML. Una volta creata un'attività del vincolo, gli autori di attività aggiungono questo vincolo alla proprietà Constraints dell'attività da convalidare o usano il vincolo per fornire convalida aggiuntiva tramite la proprietà AdditionalConstraints di un'istanza di ValidationSettings.After a constraint activity is created, activity authors add this constraint to the Constraints property of the activity to validate, or they use the constraint to provide additional validation by using the AdditionalConstraints property of a ValidationSettings instance. La logica di convalida può essere costituita da convalide semplici, ad esempio quella dei metadati di un'attività. Tuttavia una convalida può essere eseguita anche considerando la relazione dell'attività corrente con le relative attività padre, figlio e di pari livello.The validation logic can consist of simple validations such as validating an activity’s metadata, but it can also perform validation that takes into account the relationship of the current activity to its parent, children, and sibling activities. I vincoli vengono creati usando l'attività Constraint<T> e molte attività di convalida aggiuntive sono fornite per consentire la creazione di errori e di avvisi di convalida nonché per fornire informazioni sulle attività correlate nel flusso di lavoro.Constraints are authored by using the Constraint<T> activity, and several additional validation activities are provided to assist with the creation of validation errors and warnings and to provide information about related activities in the workflow.

Oggetti AssertValidation e AddValidationErrorAssertValidation and AddValidationError

L'attività AssertValidation valuta l'espressione a cui fa riferimento la relativa proprietà Assertion e se l'espressione restituisce false, un errore o avviso di convalida viene aggiunto all'oggetto ValidationResults.The AssertValidation activity evaluates the expression referenced by its Assertion property, and if the expression evaluates to false, a validation error or warning is added to the ValidationResults. La proprietà Message descrive l'errore di convalida mentre la proprietà IsWarning indica se l'errore di convalida è un errore effettivo o un avviso.The Message property describes the validation error and the IsWarning property indicates whether the validation failure is an error or a warning. Il valore predefinito per la proprietà IsWarning è false.The default value for IsWarning is false.

Nell'esempio seguente viene dichiarato un vincolo che restituisce un avviso di convalida se la proprietà DisplayName dell'attività convalidata ha una lunghezza che non supera i due caratteri.In the following example, a constraint is declared that returns a validation warning if the DisplayName of the activity being validated is two characters or less in length. Il parametro di tipo generico usato per Constraint<T> specifica il tipo di attività convalidata dal vincolo.The generic type parameter used for Constraint<T> specifies the type of activity that is validated by the constraint. Questo vincolo usa l'oggetto Activity come tipo generico e può essere usato per la convalida di tutti i tipi di attività.This constraint uses Activity as the generic type and can be used to validate all types of activities.

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 alla proprietà Constraints dell'attività, come mostrato nel codice di esempio seguente.To specify this constraint for an activity, it is added to the Constraints of the activity, as shown in the following example code.

public sealed class SampleActivity : CodeActivity  
{  
    public SampleActivity()  
    {  
        base.Constraints.Add(ActivityDisplayNameIsNotSetWarning());  
    }  

    // Activity implementation omitted.  
}  

Questo vincolo potrebbe essere specificato dall'host anche per le attività in un flusso di lavoro usando la proprietà AdditionalConstraints, illustrata nella sezione successiva.The host could also specify this constraint for activities in a workflow by using AdditionalConstraints, which is covered in the next section.

L'attività AddValidationError viene usata per generare un errore o avviso di convalida senza richiedere la valutazione di un'espressione.The AddValidationError activity is used to generate a validation error or warning without requiring the evaluation of an expression. Le relative proprietà sono simili all'oggetto AssertValidation che può essere usato insieme alle attività di controllo del flusso di un vincolo quale l'attività If.Its properties are similar to AssertValidation and it can be used in conjunction with flow control activities of a constraint such as the If activity.

Attività di relazioni di flussi di lavoroWorkflow Relationship Activities

Sono disponibili numerose attività di convalida che forniscono informazioni sulle altre attività del flusso di lavoro in relazione all'attività da convalidare.Several validation activities are available that provide information about the other activities in the workflow in relation to the activity being validated. GetParentChain restituisce una raccolta di attività contenente tutte le attività tra l'attività in corso e l'attività radice.GetParentChain returns a collection of activities that contains all of the activities between the current activity and the root activity. GetChildSubtree fornisce una raccolta di attività contenente le attività figlio nel modello ricorsivo e GetWorkflowTree ottiene tutte le attività nel flusso di lavoro.GetChildSubtree provides a collection of activities that contains the child activities in a recursive pattern, and GetWorkflowTree gets all the activities in the workflow.

Nell'esempio seguente il convalida di relazioni tra attività esempio, un CreateState viene definita un'attività.In the following example from the Activity Relationships Validation sample, a CreateState activity is defined. L'attività CreateState deve essere contenuta all'interno di un'attività CreateCountry e il metodo GetParent restituisce un vincolo che applica questo requisito.The CreateState activity must be contained within a CreateCountry activity, and the GetParent method returns a constraint that enforces this requirement. GetParent usa l'attività GetParentChain insieme a un'attività ForEach<T> per controllare le attività padre dell'attività CreateState per determinare se il requisito è stato rispettato.GetParent uses the GetParentChain activity in conjunction with a ForEach<T> activity to inspect the parent activities of the CreateState activity to determine if the requirement is met.

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  
    }  
}  

Per altre informazioni, vedere Windows Workflow Foundation convalida esempi.For more information, see the Windows Workflow Foundation Validation samples.

Vincoli aggiuntiviAdditional Constraints

Gli autori di 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 AdditionalConstraints di un'istanza di ValidationSettings.Workflow host authors can specify additional validation constraints for activities in a workflow by creating constraints and adding them to the AdditionalConstraints dictionary of a ValidationSettings instance. Ogni elemento nella proprietà AdditionalConstraints contiene il tipo di attività per il quale vengono applicati i vincoli e un elenco dei vincoli aggiuntivi per quel tipo di attività.Each item in AdditionalConstraints contains the type of activity for which the constraints apply and a list of the additional constraints for that type of activity. Quando la convalida viene richiamata per il flusso di lavoro, ogni attività del tipo specificato, incluse le classi derivate, valuta i vincoli.When validation is invoked for the workflow, each activity of the specified type, including derived classes, evaluates the constraints. In questo esempio il vincolo ActivityDisplayNameIsNotSetWarning della sezione precedente viene applicato a tutte le attività in un flusso di lavoro.In this example, the ActivityDisplayNameIsNotSetWarning constraint from the previous section is applied to all activities in a workflow.

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 proprietà OnlyUseAdditionalConstraints dell'oggetto ValidationSettings è true, solo i vincoli aggiuntivi specificati vengono valutati quando la convalida viene richiamata mediante la chiamata al metodo Validate.If the OnlyUseAdditionalConstraints property of ValidationSettings is true, then only the specified additional constraints are evaluated when validation is invoked by calling Validate. Ciò può essere utile per esaminare i flussi di lavoro per configurazioni di convalida specifiche.This can be useful for inspecting workflows for specific validation configurations. 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 per il flusso di lavoro per iniziare correttamente.Note however that when the workflow is invoked, the validation logic configured in the workflow is evaluated and must pass for the workflow to successfully begin. Per ulteriori informazioni sulla chiamata della convalida, vedere richiamare la convalida delle attività.For more information about invoking validation, see Invoking Activity Validation.