Published: 12 Jul 2010
By: Manning Publications
This article, taken from the book SharePoint 2010 Workflows in Action, shows you how easy it is to deploy an ASP.NET form to a workflow.
About the book
This is the 9th chapter of the book SharePoint 2010 Workflows in Action. It has been published with the exclusive permission of Manning.
Written by: Phil Wicklund
ASP.NET forms can be a bit tricky to develop, but they’re easy to deploy. You add the form to a workflow, SharePoint 2010 packages everything up neat and tidy, and all that’s left for you to do is to deploy the project. Once you associate the workflow to a list or initiate the workflow on an item, SharePoint will recognize and use your custom ASP.NET form! The process takes seconds!
Once deployed, you’ll notice that the form is blank. Deployment was easy, but now it’s time to put our developer hat on and add some controls to that form, so users can pass data between the form and the workflow. To illustrate this process, we’ll create a generic initiation form. (Along the way, I’ll point out differences for association forms.)
Let’s get started by creating a new sequential workflow project called TestASPNETWorkflowForms. Create a list workflow, and bind it to a list of your choice with the project provisioning wizard. After the project has been created, right-click on Workflow1, and choose Add, New Item. The new item dialog will appear (figure 1). Select a Workflow Initiation Form.
Figure 1: ASP.NET forms are extremely easy to integrate into a Visual Studio workflow. Simply right-click the workflow and add a new item.
After adding the form, SharePoint displays an ASP.NET HTML view of the form (figure 2). This auto-generated form has a button that’s wired and ready to go. To view the code behind the form, right-click it in the Solution Explorer and choose View Code. You’ll notice four auto-generated methods
Page_Load: Use this method to set default values for the fields on your form.
GetAssociationData: Our workflow calls this method to retrieve the values the user enters into the form. Simply return a string in this method that contains a serialized class with the form data stored in it. Then, on the workflow side of things, we can deserialze this class and the workflow can do something with the data.
StartWorkflow_Click: Submits the form.
Cancel_Click: Cancels the form
There’s not much to worry about with these methods because they’re complete as is. Usually, you won’t need to alter these methods, but they’re available, if you need to.
Figure 2: The auto-generated ASP.NET form has a button and controls wired and ready to go.
Return to the ASP.NET HTML view (if necessary), so we can add a few ASP.NET controls. Inside the PlaceHolderMain content placeholder, add a few text boxes. We will use these text boxes to allow the user to enter information. To ship the user input values to the workflow, we’ll use the GetInitiationData method to return a string containing the data. We don’t want to pass just any string, we need a string that represents a serialized class that both the form and the workflow can instantiate and serialize/deserialize. To this purpose, right click Workflow1, choose Add and then select New Item. Choose a class file and then name the class InitiationFormParameters. Make the class public, and add two public strings, one for each parameter in the initiation form.
Back in the code behind of the ASP.NET form, find the GetInitiationData method. Add the code in Listing 1 to this method.
Listing 1: GetInitiationData method
InitiationFormParameters data =
data.InitiationParameter1 = InitParameter1.Text;
data.InitiationParameter2 = InitParameter2.Text;
(StringWriter writer =
XmlSerializer s =
initdata = writer.ToString();
This code first creates an instance of our class and assigns properties to the user input values stored in the form . Next, it serializes that class into a string with a
StringWriter, and then returns that string.
Our workflow calls the
GetInitiationData method and loads the string into a property of the
OnWorkflowActiviated activity called
AssociationData). Next, we must deserialize the stored string in
InitializationData into a class the workflow can use. To do so, right-click the
OnWorkflowActivated activity and choose Generate Handlers. Then, replace the
onWorkflowActivated1_Invoked method with the code in Listing 2.
Listing 2 onWorkflowActivated1_Invoked method
sender, ExternalDataEventArgs e)
XmlSerializer serializer =
XmlTextReader reader =
InitiationFormParameters initiationFormData = (InitiationFormParameters)serializer.Deserialize(reader);
param1 = initiationFormData.InitiationParameter1;
param2 = initiationFormData.InitiationParameter2;
This code retrieves the user input data so the workflow can then perform some action on that data. The first thing we want to do is read the string out of the
InitiationData property (or
AssociationData) into an
XmlTextReader. Then, we want to deserialize that XML into a new object that is the same type the string was serialized into (in this case the
InitiationFormParameters object). After we have our object, we can start assigning some global variables or take other actions.
Our last step is to make sure everything is working, so add a
LogToHistoryListActivity activity below the
OnWorkflowActivated activity. We can use this history logger to render our form values on the workflow status page. After the
LogToHistoryActivity activity is added, right-click it and choose Generate handlers. In the method that was generated, add the following code to display the user input values:
+ param1 +
" Param2: "
With this activity logging our form parameters, we can start testing. First, build and deploy the project. If you hadn’t already associated the workflow to a list, do so now. Otherwise, start the workflow on an item in the list. You should see our custom ASP.NET initiation form shown in figure 3.
Figure 3: Our initiation form will prompt the user for pertinent information when the workflow starts.
Enter some values and submit the form. The form will display a status of completed. Click the status column to view the workflow status page. Figure 4 shows the workflow history, with the user input values.
Figure 4: You can tell that the code ran correctly because the values you entered via the form are displayed on the workflow status page.