共用方式為


宣告式約束條件

宣告式條件約束可為活動及其與其他活動的關係提供強大的驗證方法。 條件約束是在撰寫程式期間為活動設定,但工作流程主機也可以指定其他條件約束。 本主題提供使用宣告式條件約束來提供活動驗證的概觀。

使用宣告式約束條件

條件約束是包含驗證邏輯的活動。 此條件約束活動可以在程式代碼或 XAML 中撰寫。 建立條件約束活動之後,活動作者會將此條件約束新增至 Constraints 活動的屬性進行驗證,或使用 條件約束來提供 AdditionalConstraints 實例的 ValidationSettings 屬性來提供額外的驗證。 驗證邏輯可以包含簡單的驗證,例如驗證活動的元數據,但它也可以執行驗證,以將目前活動與其父系、子系和同層級活動的關係納入考慮。 限制是使用 Constraint<T> 活動來建立的,並提供數個額外的驗證活動,以協助生成驗證錯誤和警告,並提供有關流程中相關活動的資訊。

AssertValidation 和 AddValidationError

活動 AssertValidation 會評估其 Assertion 屬性所參考的表達式,如果表示式評估為 false,則會將驗證錯誤或警告新增至 ValidationResults。 屬性 Message 描述驗證錯誤,而 IsWarning 屬性會指出驗證失敗是錯誤還是警告。 IsWarning 的預設值為 false

在下列範例中,宣告條件約束,如果 DisplayName 所驗證活動的 長度是兩個字元或更少,則會傳回驗證警告。 用於 Constraint<T> 的泛型型別參數會指定條件約束所驗證的活動類型。 此條件約束使用 Activity 做為泛型型別,可用來驗證所有類型的活動。

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."),  
            }  
        }  
    };  
}  

若要為活動指定這項約束條件,應將其新增至活動的 Constraints,如下列範例程式碼所示。

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

主機也可以使用 AdditionalConstraints 為工作流程中的活動指定此條件約束,這部分會在下一節中涵蓋。

活動 AddValidationError 可用來產生驗證錯誤或警告,而不需要評估表達式。 其屬性類似於 AssertValidation,並可與條件約束的流程控制活動,例如 If 活動,搭配使用。

工作流程關聯性活動

有數個驗證活動可供使用,提供工作流程中與所驗證活動相關的其他活動相關信息。 GetParentChain 會傳回活動集合,其中包含目前活動與根活動之間的所有活動。 GetChildSubtree 提供一個包含子活動的集合,並且這些子活動以遞歸模式排列,而 GetWorkflowTree 獲取工作流程中的所有活動。

在下列範例中,會定義 CreateState 活動。 CreateState 活動必須包含在 CreateCountry 活動之內,而GetParent 方法會返回一個條件約束,強制執行此要求。 GetParent 使用 GetParentChain 活動搭配 ForEach<T> 活動來檢查 CreateState 活動的父活動,以判斷是否符合需求。

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

其他條件約束

工作流程主機作者可以藉由建立條件約束並將其新增至 AdditionalConstraints 實例的 ValidationSettings 字典,來指定工作流程中活動的其他驗證條件約束。 中的每個 AdditionalConstraints 專案都包含套用條件約束的活動類型,以及該活動類型的其他條件約束清單。 為工作流程叫用驗證時,指定型別的每個活動,包括衍生類別,都會評估條件約束。 在此範例中, ActivityDisplayNameIsNotSetWarning 上一節的條件約束會套用至工作流程中的所有活動。

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

如果 的 OnlyUseAdditionalConstraints 屬性 ValidationSettingstrue,則藉由呼叫 Validate來叫用驗證時,只會評估指定的其他條件約束。 這對於檢查工作流程是否有特定驗證組態很有用。 不過請注意,叫用工作流程時,會評估工作流程中設定的驗證邏輯,而且必須通過,工作流程才能順利開始。 如需叫用驗證的詳細資訊,請參閱 叫用活動驗證