Deploy SharePoint 2013 Custom Workflow Actions with SharePoint App

02/04/2015

It’s possible to deploy SharePoint 2013 custom workflow actions from a sandbox solution. If you want to deploy them with a SharePoint App, then you will run into a few obstacles.

Firstly you might get an error like this when you try to package your app.

Project file must include the .NET Framework assembly 'WindowsBase, PresentationCore' in the reference list.

If this happens you have to check the build action on your xaml file. It is probably set to compile, which is wrong it should be set to: XamlAppDef.

When this is fixed you might run into this error:
The workflow '{0}' cannot be used in an app project

This is from the Visual Studio packaging validator, that basically won’t let you add workflow actions to a SharePoint App. I checked the source code of validator it looks like this
[csharp]
internal class WorkflowAppSpisInWspRule : FeatureValidationRuleBase
{
protected override void OnValidateProjectItem(IFeatureValidationContext context, ISharePointProjectItem projectItem)
{
if (context.Feature.Project.ProjectMode != SharePointProjectMode.SharePointApp)
return;
string id = projectItem.ProjectItemType.Id;
if (!(id == "Microsoft.VisualStudio.SharePoint.Workflow4CustomActivity") && !(id == "Microsoft.VisualStudio.SharePoint.Workflow4"))
return;
context.RuleViolations.Add((IValidationRuleViolation) new ValidationRuleViolation()
{
Message = string.Format((IFormatProvider) CultureInfo.CurrentCulture, Resources.WorkflowSolutionStyleFoundInApp, new object[1]
{
(object) projectItem.Name
}),
Severity = ValidationRuleViolationSeverity.Error
});
}
[/csharp]
So what we can learn from this is.

  1. If we are not packaging and hence validating af SharePoint app, nothing is validated
  2. If we are validating a SharePoint app, then the ProjectItemType.Id must be different from “Microsoft.VisualStudio.SharePoint.Workflow4CustomActivity” and “Microsoft.VisualStudio.SharePoint.Workflow4”.

If we look into the SharePointProjectItem.spdata file (hidden per default in Visual Studio, but located in the folder with you custom workflow actions) that contains information for visual studio about the custom workflow action, we will see that per default it looks something along the lines of:
[xml]
<?xml version="1.0" encoding="utf-8"?>
<ProjectItem Type="Microsoft.VisualStudio.SharePoint.Workflow4CustomActivity" DefaultFile="DateFormat.xaml" FeatureReceiverClass="Microsoft.SharePoint.WorkflowServices.SPCustomActionPackagingFeatureReceiver" FeatureReceiverAssembly="Microsoft.SharePoint.WorkflowServices, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" SupportedTrustLevels="All" SupportedDeploymentScopes="Web" xmlns="http://schemas.microsoft.com/VisualStudio/2010/SharePointTools/SharePointProjectItemModel">
<Files>
<ProjectItemFile Source="Elements.xml" Target="DateFormat2\" Type="ElementManifest" />
<ProjectItemFile Source="DateFormat.actions4" Target="DateFormat2\" Type="ElementFile" />
<ProjectItemFile Source="DateFormat.xaml" Target="DateFormat2\" Type="ElementFile" />
</Files>
<ExtensionData>
</ExtensionData>
</ProjectItem>
[/xml]
Now it is obviously why the validation fails. What we can do is that instead of using a custom ProjectItemType like “Microsoft.VisualStudio.SharePoint.Workflow4CustomActivity” we can simply use “Microsoft.VisualStudio.SharePoint.GenericElement” because all we need is our xaml and action4 items deployed to SharePoint.

The corrected the SharePointProjectItem.spdata file might look like this
[xml]
<ProjectItem Type="Microsoft.VisualStudio.SharePoint.GenericElement" DefaultFile="Elements.xml" SupportedTrustLevels="All" SupportedDeploymentScopes="Web, Site, WebApplication, Farm, Package" xmlns="http://schemas.microsoft.com/VisualStudio/2010/SharePointTools/SharePointProjectItemModel">
<Files>
<ProjectItemFile Source="Elements.xml" Target="DateFormat2\" Type="ElementManifest" />
<ProjectItemFile Source="DateFormat.actions4" Target="DateFormat2\" Type="ElementFile" />
<ProjectItemFile Source="DateFormat.xaml" Target="DateFormat2\" Type="ElementFile" />
</Files>
</ProjectItem>
[/xml]

One last thing we need to do before we are able to deploy the custom workflow actions is that we have to use a custom feature reciever, the one you should use is:
FeatureReceiverClass=”Microsoft.SharePoint.WorkflowServices.SPCustomActionPackagingFeatureReceiver”
FeatureReceiverAssembly=”Microsoft.SharePoint.WorkflowServices, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c”