First published on TECHNET on Sep 25, 2012
This post is a contribution from Himani Sharma, an engineer with the SharePoint Developer Support team.
Requirement
You want to use custom Association and Initiation forms with your Visual Studio workflows. InfoPath forms do not fulfill your requirement due to the limitation they pose in terms of controls available in browser enabled forms. Hence you’d like to use custom ASPX forms.
Analysis
Back in SharePoint 2007 with which the preferred way of development was Visual Studio 2008, we did not have any templates to create these custom ASPX forms. Hence the entire code had to be written from scratch. The amount of effort involved was huge, since custom association and initiation forms required us to handle the association and workflow management ourselves via code.
This changed with the advent of Visual Studio 2010 (preferred IDE for SharePoint 2010). The new version comes with Visual studio templates for workflow Association and InfoPath Forms. Task Form templates are not available since those would be standard ASPX page with your custom controls and code behind. So, let’s see how we can create these ASPX forms using the Visual Studio 2010.
Steps
I assume you already know how to create a basic approval workflow in Visual Studio. If not please refer to the SharePoint Foundation SDK.
1. Open Visual Studio 2010 and create a new Sequential workflow project for SharePoint 2010.
2. Create a basic Task Approval workflow as shown below.
3. Once the basic workflow has been built and compiled, we can move to the next step of adding custom ASPX forms to it. So, select the workflow item in the project created and ‘Add New Item’.
4. Select ‘SharePoint’ > ‘2010’ from Installed Templates and scroll down to select ‘Workflow Association Form’.
5. Once the form gets added you’ll get the following view.
6. Open the .ASPX form markup and examine it. It will contain all the necessary SharePoint namespaces and master page references. The content placeholder – ‘PlaceHolderMain’ contains two buttons –‘AssociateWorkflow’ and ‘Cancel’. These have corresponding event handlers automatically added to the code behind file.
7. Since this is an association form, add a few controls in the content placeholder – ‘PlaceHolderMain’ to get data from end user. My sample will obtain username to whom task would be assigned everytime the workflow creates a task; and gets data to set the due-date for the assigned task.
NOTE : Ensure you add them above the button controls. I have added a ‘PeopleEditor’ and a ‘Datetime’ control to it.
8. Let’s create a new class type to store the data entered by user. Ensure the class is marked as [Serializable].
9. Create another class to serialize this data to XML. This XML data would be later de-serialized by the workflow and read.
NOTE: Either use same namespace as the workflow’s code behind file Or reference appropriately.
10. Now, open the code behind file for this association form. If you examine it you’d see that the template has taken care of the entire workflow association management itself. All you need to do is to get the association data. Enter the following code in the function named – ‘GetAssociationData’ (available in the template by default). This method is called when the user clicks the button to associate the workflow or the association data is edited.
11. We are basically reading the form values, storing them in object of type ‘MyCustomAssociationData’ and then serializing the object to XML.
12. Open the elements.xml file under the Workflow module. This is the workflow manifest.
13. You’d see that ‘AssociationUrl’ property is automatically set to the association form created. Note that it is being picked from Layouts folder because this is where the ASPX form will get deployed.
14. Now open the workflow code behind file. We would read the association data inside ‘OnWorkflowActivated’ event handler.
15. Create two local variables to store the data read from association form. Create an object of type – ‘MyCustomAssociationData’ class created in step 8.
16. Inside the OnWorkflowActivated’ event handler, add following code.
17. The serialized Association Data is available through WorkflowProperties.AssociationData. This data is in XML format and hence de-serialized using the XMLSerializer and XMLTextReader class, into ‘MyCustomAssociationData’ object. Once done, we store it in local variables created in step 16.
18. Next, open the feature.xml file by double clicking the feature name as shown below. This should open the properties in the properties window.
19. Add data to ReceiverAssembly and ReceiverClass properties.
20. This is all about using and consuming Association Data using ASPX forms.
21. In order to use custom ASPX Initiation form, we follow the same drill.
22. Select the workflow item in the project created and ‘Add New Item’. Note that you select the workflow module and not project module otherwise, you wouldn’t find Association and Initiation form templates.
23. Select ‘SharePoint’ > ‘2010’ from Installed Templates and scroll down to select ‘Workflow Initiation Form’.
24. Open the .ASPX form markup and examine it. It will contain all the necessary SharePoint namespaces and master page references. The content placeholder – ‘PlaceHolderMain’ contains two buttons –‘StartWorkflow’ and ‘Cancel’. These have corresponding event handlers automatically added to the code behind file.
25. Since this is an Initiation form, add a few controls in the content placeholder – ‘PlaceHolderMain’ to get Initiation data from end user. My sample workflow’s job is to create sites. The initiation form will obtain site name and site description for the site to be created when a workflow is started (NOTE: this data is obtained for each new workflow instance).
NOTE : Ensure you add them above the button controls. I have added two ‘textbox’ controls.
26. Create two classes – one to store the initiation data and other one to serialize it to XML (in the same fashion as earlier).
27. Now, open the code behind file for this Initiation form. If you examine it you’d see that the template has taken care of the entire workflow Initiation data management itself. All you need to do is to get the Initiation data from end user, store it and use it. Enter the following code in the function named – ‘ GetInitiationData’ (available in the template by default). This method is called when the user clicks submit button on custom ASPX initiation form.
28. We are basically reading the form values, storing them in object of type ‘SiteInformationForm’ and then serializing the object to XML.
29. Open the elements.xml file under the Workflow module. This is the workflow manifest.
30. You’d see that ‘InstantiationUrl’ property is automatically set to the Initiation form created. Note that it is being picked from Layouts folder because this is where the ASPX form will get deployed.
31. Now open the workflow code behind file. We would read the Initiation form data inside ‘OnWorkflowActivated’ event handler.
32. Create two local variables to store the data read from Initiation form. Create an object of type – ‘SiteInformationForm’’ class created in step 8.
33. Inside the OnWorkflowActivated’ event handler, add following code.
34. The serialized Initiation Data is available through WorkflowProperties.InitiationData. This data is in XML format and hence de-serialized using the XMLSerializer and XMLTextReader class, into ‘SiteInformationForm’ object. Once done, we store it in local variables created in step 30.
35. Repeat step 19 if you’re using only a custom ASPX Initiation Form. Once done, compile and deploy the solution.
Hope this walk-through was helpful!
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.