SharePoint Designer Workflow Action: Retrieve the File Extension

March 30, 2011

This post is over a year old, some of this information may be out of date.

This week I was a experimenting with creating SharePoint Designer workflows. After some time I noticed that it was not possible to retrieve the file extension in a SPD Reusable Workflow. Because this is a very useful action, I am going to explain it in this blog post on how to create a SharePoint 2010 Designer Workflow Action.

Another possibility is working with the “If the file type is …” action, but then you will need to predefine the file extensions.

Create a custom activity

In the following steps I am going to explain you how to create a SPD custom activity. The end result will be:

New SharePoint Designer Action
New SharePoint Designer Action
Extract File Extension Action
Extract File Extension Action
Workflow history
Workflow history

Prepare the project

  1. Start by creating a new Empty SharePoint Project. I named my project: “estruyf.SPDActivity.GetFileExtension”;
    Create an Empty SharePoint Project
    Create an Empty SharePoint Project
  2. Link it to the corresponding SharePoint site, and deploy it as a farm solution;
    Link the Project to Your SharePoint Site
    Link the Project to Your SharePoint Site
  3. Add the following references to your project:
    Insert the Following References
    Insert the Following References

Start coding

  1. Create a new class and call it “GetFileExtension”;
    Create a New Class
    Create a New Class
  2. Make it the class “public” (when this class is not set to public, SharePoint Designer gives an error that the: is inaccessible due to the protection level);
1
2
3
4
public class GetFileExtension
{

}
  1. Let your class inherit from the “System.Workflow.ComponentModel.Activity” class;
    Inherit from the "System.Workflow.ComponentModel.Activity" Class
    Inherit from the "System.Workflow.ComponentModel.Activity" Class
  2. Define the workflow fields that will be used in the SharePoint activity.;
1
2
3
4
// Fields
public static DependencyProperty __ContextProperty = DependencyProperty.Register("__Context", typeof(WorkflowContext), typeof(GetFileExtension));
public static DependencyProperty StringValProperty = DependencyProperty.Register("StringVal", typeof(string), typeof(GetFileExtension));
public static DependencyProperty SubstringVariableProperty = DependencyProperty.Register("SubstringVariable", typeof(string), typeof(GetFileExtension));

The “StringValProperty” will be used as an input value for the document name property. The “SubstringVariableProperty” will be used as an output value that is stored in a workflow variable. 5. The next step is to override the “Execute” method;

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
// Methods
 protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
{
        if (this.StringVal == null && this.StringVal == "")
        {
                this.SubstringVariable = string.Empty;
        }
        else
        {
                try
                {
                        this.SubstringVariable = Path.GetExtension(this.StringVal);
                        this.SubstringVariable = this.SubstringVariable.Replace(".", "");
                }
                catch (Exception)
                {
                        this.SubstringVariable = string.Empty;
                }
        }
        return ActivityExecutionStatus.Closed;
}
  1. The only thing that needs to be added to the code, are the properties that are part of the Activity class.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
// 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);
        }
}

Create the workflow action xml

When your code file is created, you need to register the action to SharePoint. This can be done by creating an “Actions” file and place it in the “SharePoint Root/TEMPLATE/Language Code/Workflow” folder.

SharePoint will automatically read the new file and add the custom action into the memory.

  1. Create a mapped folder to the following location: “SharePoint Root/TEMPLATE/Language Code/Workflow”;
    Mapped Folder
    Mapped Folder
  2. Add a new XML file to the folder and name it: “GetFileExtension.actions”;
  3. Place the next code block into the Actions file;
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
<WorkflowInfo>
    <Actions Sequential="then" Parallel="and">
        <Action Name="Extract the file extension"
                ClassName="estruyf.SPDActivity.GetFileExtension.GetFileExtension"
                Assembly="estruyf.SPDActivity.GetFileExtension, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1f8a604908bb57cd"
                AppliesTo="all"
                Category="Utility Actions">
            <RuleDesigner Sentence="Retrieve the file extension from the %1 string (Output to %2)">
                <FieldBind Field="StringVal" Text="Document Name" Id="1" DesignerType="TextArea" />
                <FieldBind Field="SubstringVariable" Text="File Extention String" 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="This should be the document name." />
                <Parameter Name="SubstringVariable"  Type="System.String, mscorlib" Direction="Out" DesignerType="ParameterNames" Description="Workflow variable output by this action." />
            </Parameters>
        </Action>
    </Actions>
</WorkflowInfo>

If needed change the “Classname” and “Assembly” attributes to your settings. Check if the Parameter names are the same as defined in the code file.

Webapplication feature

When you deploy your project, you will notice that the custom activity cannot be used. To be able to use this activity, an “authorizedType” entry needs to be added in the “web.config”.

To make this process a little more user friendly, you can create a web application feature event receiver that adds this “web.config” “authorizedType” entry.

  1. Add a new feature to your project;
    Web Application Feature
    Web Application Feature
  2. Add an event receiver to the feature;
  3. Add the following code block to the “FeatureActivated” method.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
        SPWebApplication wappCurrent = (SPWebApplication)properties.Feature.Parent;
        SPWebConfigModification modAuthorizedType = new SPWebConfigModification();
        modAuthorizedType.Name = "AuthType";
        modAuthorizedType.Owner = "estruyf.SPDActivity.GetFileExtension";
        modAuthorizedType.Path = "configuration/System.Workflow.ComponentModel.WorkflowCompiler/authorizedTypes";
        modAuthorizedType.Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode;
        modAuthorizedType.Value = @"<authorizedType Assembly='estruyf.SPDActivity.GetFileExtension, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1f8a604908bb57cd' Namespace='estruyf.SPDActivity.GetFileExtension' TypeName='*' Authorized='True' />";
        wappCurrent.WebConfigModifications.Add(modAuthorizedType);
        wappCurrent.WebService.ApplyWebConfigModifications();
}

After this step you can deploy your project to SharePoint.

Troubleshooting

The custom activity is shown in the actions list, but you are not able to select it.

  1. Check if the “Actions” xml file contains the correct assembly and class name.
  2. Check if the web.config contains the “authorizedType” entry.
  3. Check the assembly name and Namespace in the “authorizedType” entry.

The is inaccessible due to the protection level

Check if you made your class public.

References

Sources

Download Project

Comments

comments powered by Disqus