Search code examples
workflow-foundation-4workflow-foundationworkflow-activity

WF4 - Composite custom activity throw an strange exception when using OutArgument


I'm trying to use a composite custom activity that apply a regular expression and return a boolean if it match. The pattern is something encoded in design time. The source text is coming from an activity. This activity is also specified in design time (I've made a activity designer that allow to drop an activity as source)

But I also need to return what sub string match the expression, so I added an OutArgument to retrieve the string that match, and the string captured.

Here is the code:

public class RegularExpression : NativeActivity<bool>
{
    [RequiredArgument]
    public string Pattern { get; set; }

    public OutArgument<string> Captured { get; set; }

    [RequiredArgument]
    public Activity<string> RetrieveTextActivity { get; set; }

    protected override void CacheMetadata(NativeActivityMetadata metadata)
    {
        metadata.AddChild(this.RetrieveTextActivity);
    }

    protected override void Execute(NativeActivityContext context)
    {
        if (this.RetrieveTextActivity != null)
            context.ScheduleActivity<string>(this.RetrieveTextActivity, this.onRetrieveComplete);
    }

    private void onRetrieveComplete(NativeActivityContext context, ActivityInstance completedInstance, string result)
    {
        var regexp = new Regex(this.Pattern);
        var match = regexp.Match(result);

        this.Result.Set(context, match.Success);
        if (this.Captured != null)
            this.Captured.Set(context, match.Value);
    }
}

If I execute this activity without binding a variable to the Captured argument, it works as expected (the Result is correctly set).
But if I use the designer to add a variable, then I bind the variable to the Captured argument this error popup:

The argument of type 'System.String' cannot be used. Make sure that it is declared on an activity.

The exception is thrown when executing this line:

this.Captured.Set(context, match.Value);

Does someone have an idea why I can't set the argument ?
I also read that I shouldn't test that Captured is null, the runtime should automatically set a default value. But If I don't test, I've a NullReference when I don't bind a variable to the argument...

EDIT:
I want to add more information about the workflow itself. I've read in another topic that it may be VS. Here I just want to specify that I'm using a rehosted designer to create the workflow (and not VS). The workflow is then saved as XML in a database.
When I need to start a new workflow, I read the database, use XamlService.Load and Run the created workflow.


Solution

  • Does the error go away if you declare the argument in CacheMetadata?

    protected override void CacheMetadata(NativeActivityMetadata metadata)
    {
        metadata.AddChild(this.RetrieveTextActivity);
    
        RuntimeArgument argument = new RuntimeArgument("Captured", typeof(string), ArgumentDirection.Out);
        metadata.Bind(this.Captured, argument);
        metadata.AddArgument(argument);
    
    }
    

    EDIT: I was too quick. The above code should now compile and hopefully fix your problem.