How to Write a Validator for Custom Workflow Activity

In previous post about Writing a Custom Workflow Activity I talked about writing a basic custom workflow activity in its simplest form.  In this post I want to add another component to my custom workflow for validation.

Validation component is a good way to avoid some predictable exceptions which come from wrong inputs and cause unexpected state for your application.  Using validator component you can avoid these exceptions and give appropriate error texts before compilation to correct your input parameters.

Adding a validator component to a custom workflow is very simple and consists of two steps:

Ok, most things will be done in first step.

There is a ActivityValidator class in System.Workflow.ComponentModel.Compiler.  To build a validator you need to create a new class and derive it from this base class and override its Validate() method.  Validate() returns a ValidationErrorCollection object which consists of all validation errors for the activity.  This method also has two parameters: a ValidationManager and an object.  Later you can use this second parameter (object) to convert it to the type of your custom activity and get access to your activity components.

I want to extend the custom workflow activity that I used in my previous post to validate its Path property and use a regular expression to make sure user enters a valid path with .txt file extension.

I add a CustomActivityValidator class to my Class Library project (created in my previous post) and derive it from ActivityValidator then override Validate() method.  After that I convert object parameter to my custom activity type (named CustomActivity) and use this newly created object to get access to its Path property and validate its value.  In next step I use a regular expression to check if given Path property is valid otherwise I add a new ValidationError to my ValidationErrorCollection and finally returns this ValidationErrorCollection.

using System;

using System.Text.RegularExpressions;

using System.Workflow.ComponentModel.Compiler;

 

namespace CustomActivitySample

{

    internal sealed class CustomActivityValidator : ActivityValidator

    {

        public override ValidationErrorCollection Validate(ValidationManager manager, object obj)

        {

            CustomActivity customActivity = obj as CustomActivity;

 

            ValidationErrorCollection errorCollection = new ValidationErrorCollection();

 

            if (customActivity != null)

            {

                // Regular Expression inspired from Steve's RegExLib.Com

                Regex regEx = new Regex("([a-zA-Z]:(\\w+)*\\[a-zA-Z0_9]+)?.txt",

                    RegexOptions.IgnoreCase | RegexOptions.Multiline);

 

                if (!regEx.IsMatch(customActivity.Path))

                    errorCollection.Add(new ValidationError

                        ("String value provided for Path property is not valid!", 1984));

            }

 

            return errorCollection;

        }

    }

}

Now that I have a validator component in hand, I can simply add an ActivityValidator attribute to my custom workflow class and pass the type of this validator class to it.  Do not forget to add a reference to System.Workflow.ComponentModel.Compiler before adding this attribute.

using System;

using System.Collections.Generic;

using System.Text;

using System.Workflow;

using System.Workflow.Activities;

using System.Workflow.Runtime;

using System.Workflow.ComponentModel;

using System.Workflow.ComponentModel.Design;

using System.IO;

using System.Workflow.ComponentModel.Compiler;

 

 

namespace CustomActivitySample

{

    [ActivityValidator(typeof(CustomActivityValidator))]

    public class CustomActivity : Activity

    {

Alright, now my custom activity has a validator component and I can test it.  After compiling this custom activity to an assembly and replacing my previous custom activity in Toolbox with this new one and add it to a Sequential Workflow, I can set its properties.

If I put an invalid value for Path property (for example a path with .jpg extension), I can see that an error icon appears on top right corner of my activity.  If I click on it then it shows an error text (provided in validator component code).

It also shows this error in Error List window.

Heh, do you want to escape and build?!  Just do that to see what will happen!

Stay tuned!  Future posts about other components are coming.

[advertisement] Axosoft OnTime 2008 is four developer tools in one: bug tracking, project wiki, feature management, and help desk. It manages your development process so developers can focus on coding. Installed or Hosted – Free Single-user license -- Free 30-day team trial.

8 Comments : 01.30.07

Feedbacks

 avatar
#1
DotNetKicks.com
01.30.2007 @ 9:47 AM
You've been kicked (a good thing) - Trackback from DotNetKicks.com
 avatar
#2
Keyvan Nayyeri
02.04.2007 @ 9:19 AM
In previous posts I discussed about Writing a Custom Workflow Activity and Writing a Validator for a
 avatar
#3
Keyvan Nayyeri
02.12.2007 @ 10:53 PM
So far I've discussed about these topics about writing a custom workflow activity: How to Write a Custom
 avatar
#4
akjha
06.04.2007 @ 8:57 AM
Hi, I am going through your excellent artcle series. I created the custom activity and added a validator. But my activity doesn't get compiled even for the validation error... Can you tell me whats the problem ? Thanks
 avatar
#5
justforkix
05.15.2008 @ 11:59 PM

Hi,

Can you tell me, how can we get access to the current user and site objects inside an activity validator when it is being invoked in designmode?

Thanks for sharing this article

Pingback from Exploring Workflow Foundation Part 5: Custom activity validators « Hungry for Knowledge

 avatar
#7
Kumesh
11.25.2008 @ 4:03 AM

I created a custom validator class for my custom activity but Error messages are displayed in custom activity as well as Main parent workflow. i need to display error messages only for my custom activity.

Thanx in advance.

 avatar
#8
Babu
11.25.2008 @ 8:14 PM

I couldnt see a way to use the advantage of ActivityValidator inside dynamically created WF?

Leave a Comment