In writing Custom Activities for a re-hosted Workflow Designer, it gives me an error that there is a value required for the Required Argument if I don't have one, so I either use a null as seen below or "ALL". It does not accept null or "ALL" or anything else for a default argument. Please note that my required argument is of type string.
[RequiredArgument]
[DefaultValue(null)]
[Description(@"The status of the job to perform")]
public InArgument<string> JobStatus { get; set; }
[RequiredArgument]
[DefaultValue("All")]
[Description(@"The status of the job to perform")]
public InArgument<string> JobStatus { get; set; }
Error Message when Running the Workflow :
Workflow Console: Starting Workflow...
Could not start workflow.
Message: Failed to start workflow DynamicActivity.
Exception message: The following errors were encountered while processing the workflow tree: 'DynamicActivity': The private implementation of activity '1: DynamicActivity' has the following validation error: Value for a required activity argument 'JobStatus' was not supplied.
Stack trace: at System.Activities.Validation.ActivityValidationServices.ThrowIfViolationsExist(IList`1 validationErrors) at System.Activities.Hosting.WorkflowInstance.ValidateWorkflow(WorkflowInstanceExtensionManager extensionManager) at System.Activities.Hosting.WorkflowInstance.RegisterExtensionManager(WorkflowInstanceExtensionManager extensionManager) at System.Activities.WorkflowApplication.EnsureInitialized() at System.Activities.WorkflowApplication.Enqueue(InstanceOperation operation, Boolean push) at System.Activities.WorkflowApplication.WaitForTurn(InstanceOperation operation, TimeSpan timeout) at System.Activities.WorkflowApplication.InternalRun(TimeSpan timeout, Boolean isUserRun) at System.Activities.WorkflowApplication.Run()
Thanks for your help
Neither workflow runtime nor workflow designer will look into DefaultValueAttribute
. Searching attributes requires reflection which might be costly on performance. Moreover that's not the purpose of the attribute.
Anyway, you can either initialize the variable with a default value. On constructor, for example:
public class MyCodeActivity : CodeActivity
{
public MyCodeActivity()
{
JobStatus = "All";
}
}
or force a value through accessor. Something like this:
private InArgument<string> text = "All";
[RequiredArgument]
public InArgument<string> Text
{
get { return text ?? "All"; }
set { text = value; }
}
These are different approaches, use the one that fits into the behavior you want. In both cases the value can always be modified through XAML so a small check on runtime might be good:
protected override void Execute(CodeActivityContext context)
{
string text = context.GetValue(this.Text);
if (text == null)
{
text = "All";
}
Console.WriteLine(text);
}