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>

.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, “Courier New”, courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

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.