Table of Contents for on SharePoint 2007 WF Authoring using Visual Studio.
1. Setting up your environment for writing VS2005 workflows.
2. Writing an ultra basic workflow, deploying it, and slicing dicing how it worked.
3. Making that workflow more complex, adding if/else, and a bunch of activities that sort of make it more interesting.
4. Adding user interaction to that workflow using Infopath forms.
5. Authoring SharePoint 2007 Workflows using VS2008.
So far, in writing about writing sharepoint 2007 workflows in visual studio 2005, I have talked about setting up your environment, writing an ultra-basic WF where I demonstrated how the workflow project works. I then enhanced that example to include some branching logic to give an idea how what it is like to author a real world workflow. In this blogpost, I will enhance the previously written worklows, to include an input form.
Now, as you can see, the previously written roll of dice WF automatically picks the logged in user as the originator of the workflow, and creates a task for the originator.
Well, what if I wanted to play (roll dice) on someone else's behalf. In other words, what if I wished to be able to use an intiatiation form, and everytime the workflow started, it could ask me "Who are you playing on behalf of".
So - whenever the workflow starts, it needs to ask me for some data. Sounds like I need to create an "Inititiation Form".
Here is a complete list of the various forms a WF can use -
a) Association form - this pops up when a WF is associated with a list.
b) Initiation form - this pops up when a WF is intiated on a list item.
c) Modification form - you'd use this WF to perform a modification on the WF.
d) Task form - this can be used to substite for the task created for the WF.
The concepts between all 4 are portable, so I will move ahead with my canonical roll of dice example, and demonstrate, how to add an inititiation form to my existing WF. Here goes.
- Create the Infopath Form
- Publish the infopath form
- Modify your workflow.xml, so the WF can actually use the form.
- Modify your code, so the form's data is accessible via code.
- Deploy, Execute, and Play
Let us walk through these steps one by one. BTW - I am going to assume now that you are somewhat familiar with infopath. If you aren't - I'd recommend reading this article first, and establishing a general comfort feel with infopath first.
1. Create the infopath form
Start infopath and create a form that looks like as shown below -
The two controls you see there are a drop down combo box, and a button. Go ahead and right click on the drop down box, and go to "Properties". Change it's name to "assignee".
Under the "List Box Entries" area, choose the radio button that says "Look up values from an external datasource". Naturally since you don't have any datasources yet, you will need to click on the "Add" button to create a datasource. Go ahead and add a datasource to "receive" data from a sharepoint list. Under the SharePoint site details, add http://moss2007 (or whatever your sharepoint site is), when prompted to pick a list or library, choose "User Information List", and when prompted to pick the relevant columns, pick atleast the "Account" column.
When the datasource is added, and you are back in the infopath --> assignee properties, click on the button next to entries, and choose "Account" as the field you wish to show for the drop down box. When all is done, your drop down properties should look like as below:
Next - you need to configure the button.
Right click properties on the button, and change it's title to "Go Play!!". Click on the "Rules" button and add two rules
a) To submit the button to a new data connection. This will require you to create a new data connection, this time to "Submit", to the "Hosting Environment". Call this data connection "Submit".
b) Close the form.
Now that your form is authored, next you need to publish it.
2. Publish the form
While still in infopath, go to Tools --> Form Options. Under there, go to "Security and Trust" and change the trust level to "Domain" (if you are working in a domain), or "Full Trust" (if you don't have a domain handy). The better approach is to use digital signatures anyway.
With the trust fixed, click on "Publish form template" under Design tasks, and go through the following steps
a) Publish to a network location (the feature will take care of putting it on sharepoint).
b) Form template and pathname - publish it to a file called "InititationForm.xsn", and put it at the same location as the "feature.xml" and "workflow.xml" files are.
c) In the next screen, CLEAR OUT that textbox (Yes, clear it out, and ignore the warning)
d) Publish the form.
3. Modify your workflow.xml, so the WF can actually use the form.
Okay great, now we have added an instantiation form, we need to re-add in the instantiation form elements we took out in Ultra Basic WF.
Go ahead and modify your workflow.xml, so it looks like this -
Description="This workflow allows for roll of dice"
CodeBesideAssembly="RollOfDiceWF, Version=126.96.36.199, Culture=neutral, PublicKeyToken=788572d21f3ea9ad"
<!-- Tags to specify InfoPath forms for the workflow; delete tags for forms that you do not have -->
Now, the InstantiationURL seems pretty straightforward. What the hell is that Instantiation_FormURN?
Well, that is a unique way of identifying the infopath form. And you can get that string, by opening the published form in design mode, and going to File -->Properties.
4. Modify your code, so the form's data is accessible via code.
Now, while your published form is still open in design mode, click on File --> Save as Source Files .. and save to a scratch area. This will cause infopath to save a bunch of files, the one we are interested in here is "myschema.xsd".
Run the following command, to generate a myschema.cs out of the xsd.
xsd.exe myschema.xsd /c /o:.
Now, add the myschema.xsd to your project.
Great, now we can summon the unlimited power of the XmlSerializer to extract initiation data out of our WF Form. Go ahead and modify the createTask1_MethodInvoking event method to as below -
private void createTask1_MethodInvoking(object sender, EventArgs e)
createTask1_TaskId1 = Guid.NewGuid();
XmlSerializer serializer = new XmlSerializer(typeof(myFields));
XmlTextReader rdrMyFields = new XmlTextReader(new System.IO.StringReader(workflowProperties.InitiationData));
myFields fields = (myFields)serializer.Deserialize(rdrMyFields);
createTask1_TaskProperties1.AssignedTo = fields.assignee;
// createTask1_TaskProperties1.AssignedTo = workflowProperties.Originator;
createTask1_TaskProperties1.Title = "Congratulations, thou art ye winner!";
createTask1_TaskProperties1.Description = "You have won!!! Now go and claim your prize";
createTask1_TaskProperties1.SendEmailNotification = true;}
Great! As you can see, rather than hardwiring the originator of the workflow to the "AssignedTo", instead now I am pulling that out of the XmlSerializer/Infopath form. w00t!
5. Deploy, Execute, and Play
Now this is the easiest step. Hit F5.
As usual, go to a list, associate this WF, and start this WF, and VOILLA - you are presented with an infopath form, running in your browser when you instantiate the workflow, as shown below -
Now, our WF works well and fine, but what is "cfranklin" doing in a MOSS Workflow?
Oh that's a secret that I'll reveal in a couple of weeks.
Until then - sayonara! and hope you enjoyed this series on SharePoint 2007 WFs.