This post is migrated from previous hosting provider. There are still some issues with old posts. Please make a comment on this post with any issues.

Sandboxed workflow activities in SharePoint 2010

Tags: SharePoint 2010

One of the really great features in SharePoint 2010 is the Sandbox, which allows the end-users to upload solutions using the web interface, instead of relying on administrators adding the solutions directly to the farm. One of the things that that can be deployed to the Sandbox is custom workflow activities. These activates can then be used by the end-users building workflows with SharePoint Designer. It is really powerful to add custom sandboxed activities and it is very easy as well! In this post I will show you how to really fast build a custom sandboxed activity that breaks the permission inheritance on the item which the workflow is executed on.

Create the activity

In order to build a sandboxed activity you need to use Visual Studio 2010 and create a new Empty SharePoint project and choose to deploy it as a Sandboxed Solution. Then add a new class to the project. It is this class that will contain the logic for the activity. First make sure that the class is marked as public. Then you need to add a method which is the activity logic itself. This method must have a first parameter as a SPUserCodeWorkflowContext object and it must return a Hashtable. In this case we will use the SPListItem.BreakRoleInheritance() method on the item and since that method takes a boolean parameter, we will add that parameter to our activity as well. This parameter is added as the second in-parameter, which leaves the method definition as follows:

public Hashtable BreakRoleInheritance(
    SPUserCodeWorkflowContext context, 
    bool copyRoleAssignments);

The code required to break the role inheritance is as follows:

Hashtable ht = new Hashtable();
try {
  using (SPSite site = new SPSite(context.SiteUrl)) {
    SPWeb web = site.OpenWeb(context.WebUrl);
    SPList list = web.Lists[context.ListId];
    SPListItem currentItem = list.GetItemById(context.ItemId);
    currentItem.BreakRoleInheritance(copyRoleAssignments);
    currentItem.Update();
    ht["Result"] = "Success";
  }
}
catch (Exception) {
  ht["Result"] = "Failure";
}

First of all the Hashtable to return is created. This hash table is used to store different return values, in this case only on: Result which can be either Success or Failure. Using the SPUserCodeWorkflowContext object the SPSite, SPWeb, SPList and finally SPListItem is retrieved. On the list item the BreakRoleInheritance method is called with the copyRoleAssignments parameter. If the update works fine then the Result return value is set to Success. All exceptions are caught and a Result value of Failure is set.

Define the Activity for SharePoint Designer

imageTo be able to use this activity in SharePoint Designer we need to deploy a WorkflowActions/Action element in an Empty Module. Add a new Empty Module SPI to the project. Before editing the elements.xml file modify the automatically added feature (called Feature1) to be scoped to Site so this activity can be used within the whole Site Collection.

Then open up the elements.xml file and edit it as follows. Here is the full declarative code needed to hook up the activity to SharePoint Designer.

   1:  <Elements xmlns="http://schemas.microsoft.com/sharepoint/">
   2:    <WorkflowActions>
   3:      <Action
   4:        Name="Break Role Inheritance"
   5:        Category="Permissions"
   6:        Assembly="$SharePoint.Project.AssemblyFullName$"
   7:        ClassName="$SharePoint.Type.0bc46b26-96ca-4201-8480-6fd7d8ea598e.FullName$"
   8:        FunctionName="BreakRoleInheritance"
   9:        AppliesTo="all"
  10:        UsesCurrentItem="true"
  11:        SandboxedFunction="true">
  12:        <RuleDesigner 
  13:          Sentence="Breaks role inheritance on the item (copy current roles: %1)">
  14:          <FieldBind 
  15:            Field="copyRoleAssignments" 
  16:            Text="Copy Roles" 
  17:            Id="1" 
  18:            DesignerType="Bool"/>
  19:        </RuleDesigner>
  20:        <Parameters>
  21:          <Parameter 
  22:            Name="__Context" 
  23:            Type="Microsoft.SharePoint.WorkflowActions.WorkflowContext,                        Microsoft.SharePoint.WorkflowActions" 
  24:            Direction="In" 
  25:            DesignerType="Hide" />
  26:          <Parameter 
  27:            Name="copyRoleAssignments" 
  28:            Type="System.Boolean, mscorlib" 
  29:            Direction="In" 
  30:            DesignerType="ParameterNames" 
  31:            Description="Copy roles" />
  32:          <Parameter 
  33:            Name="Result" 
  34:            Type="System.String, mscorlib" 
  35:            Direction="Out" 
  36:            DesignerType="ParameterNames" 
  37:            Description="Result of activity"/>
  38:        </Parameters>
  39:      </Action>
  40:    </WorkflowActions>
  41:  </Elements>

Looking for the ActionFirst of all the WorkflowActions (2) and Action (3) elements are added. The Action element contains the Name (4) and Category (5) of the activity - these are visible in SharePoint Designer when browsing/searching for the Actions. The Assembly, ClassName and FunctionName is of course pointing to the actual assembly, class and method that we previously defined. Note that I'm using replaceable tokens here for the assembly and class name (read more about this in a previous post). The AppliesTo (9) indicates that this will apply to both document libraries and lists and with UseCurrentItem (10) set to true allows the action to modify the item in the list/library.

The RuleDesigner (12) element tells SharePoint Designer how to render this action in the Workflow Designer. It will write the text in the Sentence attribute and the %1 token will be replaced with the field with the specific Id. In this case the field is the copyRoleAssignments (14-18). With this configuration editing the activity in SharePoint Designer will look like this:

image

The last pieces of XML that is required for this activity is the definition of the Parameters (20). The two input parameters (the context and copyRoleAssignments) and the output parameter (via the Hashtable) is defined in the Parameter elements. The XML is quite self explanatory.

That was it, just deploy this to a Site Collection then open up SharePoint Designer 2010 and build your workflows. Remember that the activity runs in the Sandbox and therefore has its limitations.

7 Comments

  • mswin said

    Hi Wictor, I have used this sample and deploed the solution, but I could not see the workflow action in designer. Can you post the complete code that you used for this.

  • Alexander Gorlach said

    Is here: http://www.harepoint.com/Products/HarePointWorkflowExtensions/ Including the one to execute custom C#/VB.NET code from your workflow. It can help to avoid custom coding. WBR, Alexander

  • Vadim Gremyachev said

    Hi Wictor!
    Could you please verify manifest file (Elements.xml), looks like it has incorrect DesignerType for copyRoleAssignments in FieldBind and Parameter elements.

    I suppose it should be DesignerType="Dropdown" for FieldBind and Parameter elements

    Below is correct version for RuleDesigner and Parameters
    <RuleDesigner Sentence="Breaks role inheritance on the item (copy current roles: %1)">
    <FieldBind Field="copyRoleAssignments" Text="Copy Roles" Id="1" DesignerType="Dropdown"/>
    </RuleDesigner>
    <Parameters>
    <Parameter Name="__Context" Type="Microsoft.SharePoint.WorkflowActions.WorkflowContext,Microsoft.SharePoint.WorkflowActions" Direction="In" DesignerType="Hide" />
    <Parameter Name="copyRoleAssignments" Type="System.Boolean, mscorlib" DesignerType="Dropdown" Direction="In" Description="Copy roles" />
    <Parameter Name="Result" Type="System.String, mscorlib" Direction="Out" DesignerType="ParameterNames" Description="Result of activity"/>
    </Parameters>

Add a Comment

AWS Tracker

About Wictor...

Wictor Wilén is a Director and SharePoint Architect working at Connecta AB. Wictor has achieved the Microsoft Certified Architect (MCA) - SharePoint 2010, Microsoft Certified Solutions Master (MCSM) - SharePoint  and Microsoft Certified Master (MCM) - SharePoint 2010 certifications. He has also been awarded Microsoft Most Valuable Professional (MVP) for four consecutive years.

And a word from our sponsors...

SharePoint 2010 Web Parts in Action