Monday 12 September 2011

DependencyProperty , Creating your own actions in Designer for Sharepoint 2010 Workflows

If you use Sharepoint Designer to build workflows, sometimes you will feel the need of some extra actions in the designer (see below).Well Microsoft has provided with a class to do that, this class is call it DependencyProperty. MSDN defines the DependencyProperty like this: Represents a property that can be set through methods such as, styling, data binding, animation, and inheritance.

image

Create a Custom action it could be done with CKSDEV set of tools, but to be honest, I found that harder than doing it by myself. There is a beautiful post done by “E.Struyf” and another one done by Microsoft, so what I have done if following both and do the simplest Custom Action ever; display the title of the item.

Go to Visual Studio 2010-> New Project –> Sharepoint –> 2010 –> Empty Sharepoint Project and call it netsourcecodeDependencyProperty, click OK. In the next screen select Deploy as Farm Solution.

image

Right click on netsourcecodeDependencyProperty project –> Add –> Class… , call the class ItemTitle.cs click on Add. This class is the one driving the logic of our custom action… and thinking what we want to do it is to get the Item title and put it in a variable really. Set your class as public and be sure your class inherits from the Activity class. In order to make the whole thing work in our class we will need to override the Execute method. Be sure you add the following dlls:

  • microsoft.sharepoint.WorkflowActions.dll
  • system.transactions.dll
  • system.web.dll
  • system.web.services.dll
  • system.workflow.activities.dll
  • system.workflow.componentmodel.dll
  • system.workflow.runtime.dll

Copy and paste this code into your ItemTitle.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Workflow.ComponentModel;
using System.Workflow.ComponentModel.Compiler;
using System.IO;
using Microsoft.SharePoint.WorkflowActions;
namespace netsourcecodeDependencyProperty
{
    public class ItemTitle : Activity
    {
        // Fields
        public static DependencyProperty __ContextProperty =
            DependencyProperty.Register("__Context", typeof(WorkflowContext), typeof(ItemTitle));
        public static DependencyProperty StringValProperty = DependencyProperty.Register("StringVal", typeof(string), typeof(ItemTitle));
        public static DependencyProperty SubstringVariableProperty = DependencyProperty.Register("SubstringVariable", typeof(string), typeof(ItemTitle));
        // Methods
        protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
        {
            if (this.StringVal == null && this.StringVal == "")
            {
                this.SubstringVariable = string.Empty;
            }
            else
            {
                try
                {
                    this.SubstringVariable =this.StringVal;                    
                }
                catch (Exception)
                {
                    this.SubstringVariable = string.Empty;
                }
            }
            return ActivityExecutionStatus.Closed;
        }
        // Properties
        [ValidationOption(ValidationOption.Optional)]
        public WorkflowContext __Context
        {
            get
            {
                return (WorkflowContext)base.GetValue(__ContextProperty);
            }
            set
            {
                base.SetValue(__ContextProperty, value);
            }
        }
        [ValidationOption(ValidationOption.Required)]
        public string StringVal
        {
            get
            {
                return (string)base.GetValue(StringValProperty);
            }
            set
            {
                base.SetValue(StringValProperty, value);
            }
        }
        [ValidationOption(ValidationOption.Required)]
        public string SubstringVariable
        {
            get
            {
                return (string)base.GetValue(SubstringVariableProperty);
            }
            set
            {
                base.SetValue(SubstringVariableProperty, value);
            }
        }
    }
}


Go to your project, right click >Add-> Sharepoint Mapped Folder


image


Then… right click in the folder and Add->New Item-> Visual C#->Data->XML File-> and call the file ItemTitle.actions . Copy and paste this code inside ItemTitle.actions:

<?xml version="1.0" encoding="utf-8" ?>
<WorkflowInfo>
  <Actions Sequential="then" Parallel="and">
    <Action Name="Get the title from the Item"
            ClassName="netsourcecodeDependencyProperty.ItemTitle"
            Assembly="netsourcecodeDependencyProperty, Version=1.0.0.0, Culture=neutral, PublicKeyToken=36250bba35facf45"
            AppliesTo="all"
            Category="Utility Actions">
      <RuleDesigner Sentence="It gets the Title field from the %1 string (Output to %2)">
        <FieldBind Field="StringVal" Text="Document Title" Id="1" DesignerType="TextArea" />
        <FieldBind Field="SubstringVariable" Text="Item Title" Id="2" DesignerType="ParameterNames" />
      </RuleDesigner>
      <Parameters>
        <Parameter Name="__Context" Type="Microsoft.SharePoint.WorkflowActions.WorkflowContext, Microsoft.SharePoint.WorkflowActions" Direction="In" DesignerType="Hide"/>
        <Parameter Name="StringVal" Type="System.String, mscorlib" Direction="In" DesignerType="TextArea" Description="Item Title." />
        <Parameter Name="SubstringVariable"  Type="System.String, mscorlib" Direction="Out" DesignerType="ParameterNames" Description="Output Variable" />
      </Parameters>
    </Action>
  </Actions>
</WorkflowInfo>


Notice we have added the assembly with the PublicKeyToken, if you produce your own solution don’t forget to call the SN –T nameofyour.dll to get that key.


Go to the Feature, and add a new Feature, rename it as DependencyF.WebConfig and right click and Add Event Receiver. Go to DependencyF.WebConfig.EventReceiver.cs, we are going to add the code to update the web.config so uncomment public override void FeatureActivated(SPFeatureReceiverProperties properties) and add this code:

public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
  SPWebApplication _spwpWebApplication = (SPWebApplication)properties.Feature.Parent;
  SPWebConfigModification _spwcAuthType = new SPWebConfigModification();
  _spwcAuthType.Name = "AuthType";
  _spwcAuthType.Owner = "ItemTitle";
  _spwcAuthType.Path = "configuration/System.Workflow.ComponentModel.WorkflowCompiler/authorizedTypes";
  _spwcAuthType.Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode;
  _spwcAuthType.Value = @"<authorizedType Assembly='netsourcecodeDependencyProperty, Version=1.0.0.0, Culture=neutral, PublicKeyToken=36250bba35facf45' Namespace='netsourcecodeDependencyProperty' TypeName='*' Authorized='True' />";
  _spwpWebApplication.WebConfigModifications.Add(_spwcAuthType);
  _spwpWebApplication.WebService.ApplyWebConfigModifications();
}

 


Again, have a look to the PublicKeyToken and be sure that de key is ok. The name of the class can be obtained from here, Right click Project->Properties, you see user Assembly Name.and Default namespace:


image


Before deploy anything be sure you have everything right other wise it will not work so check:



  1. Feature: Assembly name, keys, class name, namespaces.

  2. Mapped folder: Be sure is pointing to {SharePointRoot}\Template\1033\Workflow.

  3. Package: Be sure you have Workflow and DepencyFeature inside the package.

  4. On ItemTitle.actions: Be sure your code is right and the class is public

If you have checked everything, just deploy your solution and go to Sharepoint Designer, cerate a new workflow, in the Actions list your should have our solution.


image


Beautiful isn’t it? , if you click you should get this:


image


Enjoy!


To get the project just click in the icon below.


image

No comments: