I am making a custom Activity for SharePoint 2010. When I drop the activity in the SharePoint Designer and supply values for the parameters, I get a mysterious validation error that simply says:
This action has required parameters that are missing.
Here's the source code for the action:
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Workflow.ComponentModel;
using System.Workflow.Activities;
using System.Workflow.ComponentModel.Compiler;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WorkflowActions;
namespace SharePoint.Activities.IO
{
public partial class CopyFile : SequenceActivity
{
public CopyFile()
{
InitializeComponent();
}
public static DependencyProperty SourceDirectoryProperty = DependencyProperty.Register("SourceDirectory", typeof(string), typeof(CopyFile));
public static DependencyProperty TargetDirectoryProperty = DependencyProperty.Register("TargetDirectory", typeof(string), typeof(CopyFile));
public static DependencyProperty ActionResultProperty = DependencyProperty.Register("ActionResult", typeof(string), typeof(CopyFile));
public static DependencyProperty CreateDateProperty = DependencyProperty.Register("CreateDate", typeof(DateTime), typeof(CopyFile));
public static DependencyProperty CompletionDateProperty = DependencyProperty.Register("CompletionDate", typeof(DateTime), typeof(CopyFile));
public static DependencyProperty WFContextProperty = DependencyProperty.Register("WFContext", typeof(WorkflowContext), typeof(CopyFile));
[Description("Path the files to perform the operation on")]
[Browsable(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
[ValidationOption(ValidationOption.Required)]
public string SourceDirectory
{
get { return (string)GetValue(SourceDirectoryProperty); }
set { SetValue(SourceDirectoryProperty, value); }
}
[Description("Path the files are copied to")]
[Browsable(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
[ValidationOption(ValidationOption.Required)]
public string TargetDirectory
{
get { return (string)GetValue(TargetDirectoryProperty); }
set { SetValue(TargetDirectoryProperty, value); }
}
[Description("Once the the operation completes, this is set to OK or the exception information")]
[Browsable(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
[ValidationOption(ValidationOption.Optional)]
public string ActionResult
{
get { return (string)GetValue(ActionResultProperty); }
set { SetValue(ActionResultProperty, value); }
}
[Description("When the request was created")]
[Browsable(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
[ValidationOption(ValidationOption.Optional)]
public DateTime CreateDate
{
get { return (DateTime)GetValue(CreateDateProperty); }
set { SetValue(CreateDateProperty, value); }
}
[Description("When execution stoped")]
[Browsable(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
[ValidationOption(ValidationOption.Optional)]
public DateTime CompletionDate
{
get { return (DateTime)GetValue(CompletionDateProperty); }
set { SetValue(CompletionDateProperty, value); }
}
[Browsable(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public WorkflowContext WFContext
{
get { return (WorkflowContext)GetValue(WFContextProperty); }
set { SetValue(WFContextProperty, value); }
}
//protected override void Initialize(IServiceProvider provider)
//{
// TraceIn();
// base.Initialize(provider);
// TraceOut();
//}
protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
{
TraceIn();
Debugger.Break();
var isSiteAdmin = false;
CreateDate = DateTime.Now;
try
{
// Needs administrative credentials to get the web application properties ino
SPSecurity.RunWithElevatedPrivileges(delegate
{
using (var site = new SPSite(WFContext.Site.ID))
{
using (var web = site.AllWebs[WFContext.Web.ID])
{
isSiteAdmin = web.CurrentUser.IsSiteAdmin;
if (string.IsNullOrEmpty(SourceDirectory)) throw new ArgumentException("SourceDirectory cannot be null or empty");
if (!Directory.Exists(SourceDirectory)) throw new DirectoryNotFoundException("Could not find source directory: \"" + SourceDirectory + "\"");
if (string.IsNullOrEmpty(TargetDirectory)) throw new ArgumentException("TargetDirectory cannot be null or empty");
if (!Directory.Exists(TargetDirectory)) throw new DirectoryNotFoundException("Could not find target directory: \"" + TargetDirectory + "\"");
// Do something
Debug.WriteLine(string.Format("Doing something amazing from {0} and moving it to {1}", SourceDirectory, TargetDirectory));
}
}
});
ActionResult = "OK";
}
catch (Exception ex)
{
ActionResult = isSiteAdmin ? ex.ToString() : ex.Message;
}
CompletionDate = DateTime.Now;
var result = base.Execute(executionContext);
TraceOut();
return result;
}
private static void TraceIn()
{
Trace("Entering");
}
private static void TraceOut()
{
Trace("Exiting");
}
private static void Trace(string direction)
{
Debugger.Launch();
var stackTrace = new StackTrace(2, false);
var frame = stackTrace.GetFrame(0);
Debug.WriteLine(direction + " " + frame.GetMethod().Name);
}
}
}
Here is the .action file.
<?xml version="1.0" encoding="utf-8" ?>
<WorkflowInfo>
<Actions
Sequential="then"
Parallel="and">
<Action
Name="IO Activities"
ClassName="SharePoint.Activities.IO.CopyFile"
Assembly="SharePoint.Activities.IO, Version=1.0.0.0, Culture=neutral, PublicKeyToken=abfb622251cf6982"
Category="Custom Actions"
AppliesTo="all">
<RuleDesigner
Sentence="CopyFiles from %1 to %2">
<FieldBind
Field="SourceDirectory"
DesignerType="String"
Id="1"/>
<FieldBind
Field="TargetDirectory"
DesignerType="String"
Id="2"/>
</RuleDesigner>
<Parameters>
<Parameter
Name="SourceDirectory"
Type="System.String, mscorlib"
Direction="In"
DesignerType="StringBuilder"
Description="Directory where the source files are to move" />
<Parameter
Name="TargetDirectory"
Type="System.String, mscorlib"
Direction="In"
DesignerType="StringBuilder"
Description="Directory where the files will be placed" />
<Parameter
Name="ActionResult"
Type="System.String, mscorlib"
Direction="Optional"
DesignerType="Hide" />
<Parameter
Name="CreateDate"
Type="System.DateTime, mscorlib"
Direction="Optional"
DesignerType="Hide" />
<Parameter
Name="CompletionDate"
Type="System.DateTime, mscorlib"
Direction="Optional"
DesignerType="Hide" />
<Parameter
Name="WFContext"
Type="Microsoft.SharePoint.WorkflowActions.WorkflowContext, Microsoft.SharePoint.WorkflowActions"
DesignerType="Hide" />
</Parameters>
</Action>
</Actions>
</WorkflowInfo>
Here's a link to my post on social.msdn.microsoft.com.
I've even tried removing all of the parameters by commenting out the parameters in the .actions files, the properties in the class, and commenting out the DependencyProperties. I still get the same error.
Ultimately, it looks like the issue (after I tore the project down and started over) was an incorrect designer type and a missing .
Here is the old code:
<FieldBind Field="Result" DesignerType="TextArea" Text="Action result message; returns OK on success" Id="3" />
Here is the correct code:
<FieldBind Field="Result" DesignerType="ParameterNames" Text="Action result message; returns OK on success" Id="3" />
Once that change was made, everything seems to be working.