SharePoint Workflow Basics, Part 1
One of the greatest new features of SharePoint 2007 (and the .NET Framework) is the addition of Windows Workflow. If you have ever worked with Windows Workflow natively as part of .NET Framework 3.0, you already know Windows Workflow is a powerful and flexible workflow engine. You also know that Windows Workflow is a workflow engine, and not an application itself; meaning that you must write the code to host the workflow runtime in the .NET applications you build. Now enters SharePoint, your "out of box" host for Windows Workflows. With SharePoint 2007 workflow developers no longer need to worry about how to host the workflow runtime to execute business processes; all of that complexity (hosting the workflow, providing services for transactions and persistence, etc) is taken care of for you by Windows SharePoint Services, the base of SharePoint Server 2007.
To most SharePoint people, this announcement is nothing new. Many have proclaimed the glory which is SharePoint workflow. And in fact, there are plenty of samples of SharePoint workflow solutions within the SharePoint internet community and also within the SharePoint SDK itself. But after presenting SharePoint workflow at a local technology conference, something was apparent in the kind of questions that were raised by the audience. Although there were many examples of SharePoint workflows floating around (I generated a few myself), there weren't as many great step-by-step, detailed walkthroughs of building Workflows in SharePoint starting from the basics. This post is the first attempt of bridging that gap, explaining how an experience .NET developer who is experienced with Windows Workflow can host their workflows in a SharePoint environment; step by step.
Let's start with some assumptions. I assume:
- You already are an experienced .NET 2.0 developer
- You have some experience working with SharePoint and some experience customizing SharePoint (you know what a feature is)
- You have some experience with Windows Workflow - the architecture, basic activities, etc
And next let's set some expectations of what you will get from reading this article:
- Step by step guidance on how to use Visual Studio Extensions for WSS (1.1 CTP) to build a basic workflow
- How to package your workflow as a SharePoint feature
- A very basic introduction to workflow activities for SharePoint
My intent is to keep this walkthrough at a very introductory level, only looking at the very basics needed to build, deploy, and execute a workflow within SharePoint. Future articles will build onto this example, adding more useful functionality and introducing more complex subjects like custom association forms, initiation forms, InfoPath Services, content type association, etc. So let's get started...
The first thing you're going to need is a basic development environment. I recommend using Virtual PC 2007 for local desktop development because it allows you to run the necessary SharePoint server infrastructure (Windows Server 2003, AD, SQL, etc) safely from your desktop. Plus, if you use Virtual PC, you can use the publicly available Virtual PC virtual hard drives that come pre-installed with all the MOSS prerequisites - Windows Server, AD, SQL, .NET 2.0 & 3.0, and SharePoint 2007. You can get this prebuilt image here:
My walkthrough from this point forward assumes you're using this image - if you're not you'll need to translate my instructions to the environment that you are using. In addition to the base MOSS image, you will also want to install:
- Visual Studio 2005 Team Suite Trial https://www.microsoft.com/downloads/details.aspx?FamilyID=5677ddc4-5035-401f-95c3-cc6f46f6d8f7&DisplayLang=en
- VS extensions for Windows Workflow https://www.microsoft.com/downloads/details.aspx?FamilyId=5D61409E-1FA3-48CF-8023-E8F38E709BA6&displaylang=en
- VS extensions for SharePoint https://www.microsoft.com/downloads/details.aspx?FamilyID=3E1DCCCD-1CCA-433A-BB4D-97B96BF7AB63&displaylang=en
- MOSS SDK
Once you have all of the prerequisites installed, you can proceed onto the next steps...
Step 1: Start a new Workflow Project within Visual Studio
I know some of you are already wondering why I immediately reach for Visual Studio vs. SharePoint designer. I don't intend on going into great detail into this matter, but in short here is my reasoning:
- VS workflows can be packaged as features and reused in many lists/sites in a SharePoint environment
- VS workflows allow code behinds - you can write .NET code within activities
- VS workflow allow both sequential and state machine models
Ok, so now that we decided on Visual Studio, let's create a new SharePoint Server Sequential Workflow project:
- Start Visual Studio 2005
- Create a new SharePoint Sequential Workflow project
- Click on File->New Project...
- Expand the C# node in the projects tree. Select SharePoint
- Select the Sequential Workflow
- Leave the default values for Name, Location and Solution Name - In a real production scenario you'll want to specify values that make sense for your project, but for this demonstration's purpose the defaults will do.
You should now have a new solution with a new workflow project. Notice that you get a few additional default folders and files that normally aren't included with the default Windows Workflow project
- Deployment Files - this folder contains the files that will be deployed to the SharePoint server (in addition to the project output)
- Feature Files - this folder contains the files that define your SharePoint feature
- Feature.xml - this is your feature manifest. All features are defined in this format. For a complete description of the feature.xml schema, see the SharePoint Services SDK (https://msdn2.microsoft.com/en-us/library/ms475601.aspx )
- Workflow.xml - this is the element manifest for your feature. All features are made up of elements (workflow is a type of element) and elements are defined in xml format. For a complete description of the various element schemas, see the SharePoint Services SDK (https://msdn2.microsoft.com/en-us/library/ms414322.aspx ). For information regarding workflow elements, see (https://msdn2.microsoft.com/en-us/library/ms431799.aspx )
- ProductionDeployment - this is the folder that contains the files needed to create a Windows SharePoint Solution Package (WSP). The topic of WSPs are outside the scope of this post, but know that WSPs are packages (CAB files actually) that contain features (and other elements) and are the preferred mechanism for customization deployment in production SharePoint environments. For more information regarding solution packages, see the SharePoint Services SDK (https://msdn2.microsoft.com/en-us/library/ms413687.aspx ). If you chose to build a Release build of your workflow project a WSP file will be created and deployed to your local SharePoint installation.
- PostBuildActions.bat - This file contains all the command line commands used to deploy and activate your feature. If you open the workflow project's properties window and navigate to the build events tab, you'll see that this batch file is called in the post build actions.
One thing to note is the parameter "NODEPLOY" at the end of the call to PostBuildActions.bat. By default the parameter is set to NODEPLOY which means you can build the project but the project output will not be deployed to the local SharePoint server. If you change this parameter to "DEPLOY" the batch file will attempt to deactivate, uninstall, deploy, re-install, and activate your feature on the local SharePoint server.
- Workflow1.cs - This is your workflow. This is where your arrange workflow activities and write code to execute processes
Step 2: Complete the feature.xml file
- Insert the "Feature.xml Code" snippet into the feature.xml file
- Open feature.xml
- Right click in the code editor add select insert snippet
If you don't see a "SharePoint Server Workflow" folder, see Appendix A to learn how to configure the SharePoint Server Workflow snippets using Visual Studio's Snippet Manager.
- c. Insert the feature.xml code snippet
Your feature.xml file should now look like this:
The feature.xml code snippet inserts the basic xml markup needed to define a SharePoint feature:
- Id - This is a unique identifier for your feature. All features are identified by guids in SharePoint. Use GuidGen to create a new guid (in registry format) and paste the value here.
- Tools->Create GUID->Registry Format->New Guid-> Copy
- Tile - A label for your feature. If your feature is visible in the SharePoint administration UIs, this title will appear in the list of features to be activated or deactivated.
Type "This is the title of my feature"
- Description - This is a more verbose explanation of what the feature does. This too will appear in the SharePoint feature admin UIs next to the feature title.
Type "This is my feature description"
- Version - this is a System.Version compliant string indicating the version of the feature. This value can be any version number and does not change the behavior of the feature.
Leave the default "12.0.0.0".
- Scope - determines where a feature is available for activation. Four values can be used for scope
- Farm - the feature is activated at the farm level using STSADM
- WebApplication - the feature is activated at a web application level using Central Administration
- Site - the feature is activated at the site collection level from Site Collection Settings
- Web - the feature is activated at a site level from Site Settings
Leave the default value
- ReceiverAssembly - Optional text that defines what assembly will handle your feature's events. For more information about feature events, see the Windows SharePoint Services SDK (https://msdn2.microsoft.com/en-us/library/ms469501.aspx ).
Leave the default value
- ReceiverClass - Used with ReceiverAssembly, this optional attribute specifies the .NET class within the ReceiverAssembly that handles your features events. Leave the default value here. For more information about feature events, see the Windows SharePoint Services SDK (https://msdn2.microsoft.com/en-us/library/ms469501.aspx )
Leave the default value
- ElementManifest - Specifies a relative path to an xml file that defines one or more feature elements (workflow, modules, custom actions, etc).
Leave the default value .
- ElementFile - Specifies any files that are required for the feature.
Delete this element for this demo.
- Properties - Allows feature designers to provide key/value pairs that can be retrieved at runtime via the SPFeature class's Properties member
Delete this node for this demo.
When you are finished, your feature.xml file should look like this:
Step 4. Sign your workflow assembly
Your workflow assembly will be installed in the GAC, so it must be strongly signed. To sign your assembly use Visual Studio
- Open the project properties and navigate to the Signing Tab
- Ensure "Sign the assembly" is checked
- On the choose a strong name key file drop down, select "<New...>"
- On the "Create Strong Name Key" screen provide a name for your snk file
- Build the solution - this will create an output assembly and sign that assembly with the key you created in step 4
- Get the public key token from the output assembly. You can use sn.exe to do this or what I recommend is to configure sn.exe as an external tool within Visual Studio. There's a great walkthrough on how to do this here: Scott Hiller blog to register SN https://ablog.apress.com/?p=1379. Once you have the public key token, copy it down, you will need it in the next step
Step 5: Complete Workflow.xml
- Insert the "Workflow.xml Code" snippet into the workflow.xml file
- Open workflow.xml
- Right click in the code editor and select insert snippet
-
- Insert the Workflow.xml code snippet
Complete the workflow xml file
- Name - A label for your workflow. This title will appear in the workflow association screens where site designers will attach the workflow to a list. Think of this name as the title of the feature template, not the name of any instance of the workflow.
Type "My First Workflow"
-
- Description - A more verbose description of what your workflow will do once executed. This text appears alongside the name of the workflow.
Type "My Workflow Description"
-
- ID - A unique identifier for the workflow. This must be a Guid in registry format.
Use GuidGen to create a new Guid for this attribute.
-
- CodeBesideClass - this is the fully qualified class name for your workflow code behind class.
If you left the defaults in previous steps, this should be "SharePointWorkflowLibrary1.Workflow1"
-
- CodeBesideAssembly - this is the fully qualified assembly name that hosts your workflow code behind class. If you left the defaults in previous steps, this should be "SharePointWorkflowLibrary1, Version=1.0.0.0, Culture=neutral, PublicKeyToken= <INSERT TOKEN FROM STEP 4 PART 6> ". Be sure to replace the public key token with the your public key token
- TaskListContentType - Used to specify the content type of the tasks created by this workflow. This is out of scope for this example (we'll cover this in later articles).
Delete this attribute
-
- AssociationURL - Used to specify a custom association form for your workflow. This is out of scope for this example (we'll cover this in later articles).
Delete this attribute
-
- InstantiationURL - Used to specify a custom instantiation form for your workflow. This is out of scope for this example (we'll cover this in later articles).
Delete this attribute
-
- Modification URL - Used to specify a custom modification form for your workflow. This is out of scope for this example (we'll cover this in later articles).
Delete this attribute
-
- StatusUrl - Obsolete. Do not use
- Metadata element - Contains additional information used by the workflow. For more information regarding workflow metadata see the SharePoint Services SDK (https://msdn2.microsoft.com/en-us/library/aa544212.aspx ).
This is out of scope for this example so delete this element
When you are finished you should end up with a workflow file that looks something like this:
Step 6: Add some logic to your workflow
Once you have configured the feature.xml and workflow.xml files, it time to get to the real work of add logic to your workflow. In this example we are not going to do much at all in our workflow; the purpose of this post is to illustrate how to get a simple workflow project started and deployed to a SharePoint site.
- Open the workflow in the workflow designer. Double click on Workflow1.cs and the workflows designer should appear:
- Next, let add a LogToHistoryList activity to write a message to the workflow history log to prove the workflow has executed
- Open the Visual Studio tool box window and find the LogToHistoryList activity
-
- Either drag the LogToHistoryList activity onto the designer (drop it between the onWorkflowActivated1 activity and the red end marker) or simply double click the activity in the toolbox
Your workflow should now look like this:
- Now configure the LogToHistoryActivity so that it actually writes a message to the log. To do this, you need to set the HistoryDescription property:
You can either hardcode a message by type a string into the HistoryDescription field or you can provide a dynamic message at runtime by binding this property to either a property or field in the workflow code behind. A nice feature of Windows Workflow is that it is really simple to bind workflow activities to properties of the workflow:
-
- Click on the ellipses next to the history description property
- Next tab to the "Bind to a new member" tab
-
- Leave the defaults and click ok. What this will do is add a new property called "logToHistoryListActivity1_HistoryDescription1" to your workflow code behind class; and in your workflow initialize function it will bind the activity's HistoryDescription property to this new workflow property
- Next let's write some code in the workflow code behind to set the value of the logToHistoryListActivity1_HistoryDescription1 property.
- Right click on the LogToHistoryActivity activity shape in the workflow designer view.
- On the context menu, select "Generate Handlers" - this will create a new method called logToHistoryActivity1_MethodInvoking to your workflow code behind and will open the workflow in code view
- Add code to the logToHistoryActivity1_MethodInvoking method to set the value of logToHistoryListActivity1_HistoryDescription1. Type the following code:
-
- Build the solution. If the build is successful, proceed to the next step
Step 7: Set the project post build to deploy the workflow
Once you have a configured feature and workflow, and the workflow compiles successfully, it's time to test it by deploying it to the local SharePoint instance.
- Open the project properties window
- On the Build events tab, navigate to the end of the Post-build event command line
- Change the last parameter of the post build from "NODEPLOY" to "DEPLOY"
- Rebuild the Solution
What this will do is execute the PostBuildEvent.bat file found in the project. Since we have left all the defaults, we shouldn't have to modify the batch file - but in most cases you will have to modify this file to get it to work against your own development environment. The exact detail of what the batch file is doing is beyond the scope of this post, but in short the batch file:
- Adds the project output to the local GAC
- Copies the feature files to the local SharePoint features folder
- Verifies InfoPath forms, if any exist
- Deactivates the feature if previously installed
- Uninstalls the feature
- Re-installs the feature
- Activates the feature
Once these steps complete, the workflow is ready to test in the local SharePoint environment
Step 8: Test the feature in SharePoint
To test your new feature you need perform a few actions in SharePoint. First, you will need to associate the workflow to a list or library. This allows instances of the workflow to be executed against items in the list. Next you need to instantiate the workflow by executing the workflow against an item in the list or library. This creates a new instance of the associated workflow and executes it. Finally, you will want to view the workflow history log to verify your workflow actually executed successfully.
Associate the workflow
- 1) Create a new library in the local SharePoint site. Open https://localhost/, this will redirect you to https://litwaredemo/ if you are using the sample VPC. Create a new document library called "Test"
- 2) Open the document library settings for "Test". Under permissions and management, click workflow settings
- 3) On the "Change Workflow Settings" page, click "Add a Workflow"
- 4) Next, select "My First Workflow" in the workflow templates list and provide a name for this unique association of the template. Use "Test Workflow"
- 5) Navigate back to the document library. Create a new document called "Sample". Your library should now have a 1 document:
- 6) On the ECB menu, select workflows
- 7) Next, click the "Test Workflow" workflow to execute our new workflow against our sample document
- 8) If all goes well, the workflow should execute and you should be taken back to the document library. Notice that there is a new column in the list with the title "Test Workflow". As new workflows are executed against items in a list the system will create a column for the workflow status. Click on the completed link to get more information about the workflow and the view the workflow history
- 9) Notice the workflow history section. This is where the "LogToHistoryActivity" activities log their messages. You should see the message we created in the MethodExecuting method of the workflow
Conclusion
Hopefully everyone now can create new workflow project and deploy them to their test environments for test execution. In out example our workflow really didn't do anything useful, but it did demonstrate how to access the item the workflow is executing against so more complex logic could be implemented. In future articles, we will create more complex workflows that really exercise the powerful features of SharePoint workflow
Appendix A
How to configure SharePoint Workflow snippets in Visual Studio 2005
If you are reading this appendix, then I assume Step 2 did go as planned. No fear, adding the SharePoint workflow code snippets is just a few clicks away:
- 1) Open the snippet manager - Press CTRL-K, CTRL-B
- 2) When the snippet manager window appears, click the "Add" button
- 3) Navigate to the following dir: C:\Program Files\Microsoft Visual Studio 8\Xml\1033\Snippets\SharePoint Server Workflow. Click Open
- 4) You should now see a SharePoint Server Workflow folder in the manager window
- 5) Click OK. Your snippets are ready to use. Return back to Step 2
Comments
Anonymous
October 01, 2007
PingBack from http://www.artofbam.com/wordpress/?p=4423Anonymous
October 03, 2007
Thanx Tom! Top-notch instructions and screens! Can't wait for the next part!Anonymous
December 09, 2007
hi, what happens when a sharepoint workflow is in progress and server is restarted.Anonymous
June 11, 2008
Hi Tom, Its very informative, and I enjoy reading Part1 of this series. Do you have any plan for writing the remaining parts of this series? Thanks, SanjayAnonymous
August 18, 2008
I'm tring to install a Workflow in a Farm scope. But I receive the following error: "Elements of type 'Workflow' are not supported at the 'Farm' scope. This feature could not be installed." Have any idea? Ueslei