A few months ago, I was asked to build a SharePoint 2010 workflow using Windows Workflow Foundation and InfoPath Forms. At first, the workflow seemed pretty basic, but as usual, the scope began to creep and I was compelled to get creative with our original design decision.
What I had to figure out was how to use the InfoPath Form data to drive the workflow. I needed more than the standard promoted form field. I also had to be able to evaluate things like last user to open the form or set the next form view programmatically. I was hoping it would not be too difficult and after a little digging, it turned out that it’s really not.
Before we take a deeper dive, I will first provide a really basic overview of how SharePoint uses InfoPath Forms to store data.
How SharePoint Uses InfoPath Forms to Store Data
When you publish an InfoPath Form to a SharePoint Form Library, the library stores the form definition it needs in order to correctly render the form, stores the entered information, and applies any security or permissions it needs to operate correctly. On the other hand, when the user fills out and saves the form to the library, only an XML document containing the form fields is saved. The XML document’s schema follows the hierarchy of the fields in your InfoPath Form. For example, when the data for the following field list (Figure 1) is saved to the SharePoint Form Library, the resulting XML file will have the schema shown below (Figure 2).
You can probably see where I’m going with this. All that needs to be done at this point is to parse the workflow item XML during execution and read or update values.
Creating a Reusable Helper Class
Once I figured out the process, it turned out to be just complicated and uniform enough that it was the perfect candidate for a helper class. Thus, I chose an abstract base class that I creatively called, InfoPathForm – you can download this class at the bottom. The class is pretty simple; however, I do want to point out a few key sections of code.
The constructor accepts the SPFile and a root XML path (if any).
The SPFile is the XML document we talked about earlier and is retrieved by calling WorkflowProperties.Item.File. The root path is the root path of your InfoPath field list. In Figure 2 above, it is the ‘MyFields’ element. With this information, the InfoPathForm class has everything it needs to parse the file into an XML document.
The class then exposes several protected functions for an extended class to interact with the parsed form data.
Finally, if any data changes are made to the form data, the InfoPathForm class exposes a save function, which updates the SP file with any modified values.
In a real world scenario, we might have an InfoPath Form that captures customer order information. We could extend the InfoPathForm base class with a CustomerOrder class. This extended class could expose members like CustomerName, CustomerAddress, and OrderDetails. Each of these properties could invoke one of the ‘Get’ or ‘Set’ methods in the InfoPathForm class to read and update the CustomerOrder data.
That’s it, pretty simple! If you find that you need to parse an InfoPath Form, I hope this post will help save you a little time.
As a possible improvement, the current InfoPathForm class that I’ve included with this post can read a repeatable field, but it can’t save it back to the document yet. If you need to update the field list once you’ve read it, you’ll need to create that code yourself.
To learn more about SharePoint or other Microsoft solutions, please contact Credera’s Microsoft Solutions group.