RSS Feed Feed your read!

Bookmark and Share







Tag Cloud

ASP.NET Generic, Best Practices, Business Intelligence, Freeware Releases, InfoPath, Infrastructure, jQuery, Lunch & Learn Events, Project Server, Random, Reporting Services, Search, SharePoint Administration, SharePoint Business Analysis and Project Management, SharePoint Development, Silverlight, Social Networking, Speaking Events, White Paper Releases, Workflow Foundation,

Archives

June 2007 (3)
August 2007 (1)
November 2007 (2)
February 2008 (2)
April 2008 (5)
May 2008 (7)
June 2008 (8)
July 2008 (7)
August 2008 (3)
September 2008 (7)
October 2008 (1)
November 2008 (3)
December 2008 (3)
January 2009 (7)
February 2009 (5)
March 2009 (10)
April 2009 (2)
May 2009 (6)
June 2009 (3)
July 2009 (4)
August 2009 (6)
September 2009 (3)
October 2009 (9)
November 2009 (10)
December 2009 (1)
January 2010 (1)
February 2010 (3)
March 2010 (6)
April 2010 (2)
May 2010 (3)
June 2010 (4)
July 2010 (3)

InfoPath and Visual Studio Workflows – 3 Great Tricks (2 of 3) 

Tags: InfoPath, Workflow Foundation

In my second part of my three part series (Part 1 – Part 3), I'm going to show how you can use a visual studio workflow to programmatically react to and read user entered data in a custom InfoPath form. Now I could jump right to the chase and just talk about what code you use to get at the data in an InfoPath form, however I think it may benefit some to see how you leverage that code in a SharePoint workflow, and how to build that workflow from scratch. Hence, I'll be taking the scenic route with this post J. If you're just looking for code to copy, skip to step X below.

 

Of the three posts in this series, the business case for this post is the most straight forward. There are many reasons why one would want to programmatically access InfoPath form data. What will be demonstrated in this post is reading data out of a submitted expense report, possibly because one would want to send the expense report dollar amount to some accounting system – who knows… The expense report example is rather generic, but I hope it will serve to demonstrate the concept.

 

Here are the steps to accomplish this at a high level:

 

1. Create a new Visual Studio sequential workflow project
2. Create necessary feature files to deploy the workflow to SharePoint
3. Generate a proxy class off your InfoPath form
4. Add appropriate workflow activities that Serialize the form's XML into the proxy object
5. Deploy and Test!

 

Step by Step Walkthrough (10 EASY STEPS!):

 

1. Create a new Visual Studio sequential workflow project

 

 

2. Sign the assembly – this is necessary because all SharePoint workflows need to be deployed to the GAC (c:\windows\assembly)

 

 

3. Add feature files to deploy the workflow

 

Right click on the project and add two XML files, named Feature.xml and Elements.xml:

 

 

[Note: The better way to deploy features is to use Solutions, however for the sake of brevity; I'll be deploying this feature manually.]

 

 

4. Replace code in feature files

 

Feature.xml:

<?xml version="1.0" encoding="utf-8"?>
<Feature Id="[Guid]"
        Title="Expense Report Workflow"
        Description="desc."
        Version="1.0.0.0"
        Scope="Site"
        xmlns="http://schemas.microsoft.com/sharepoint/">
    <ElementManifests>
        <ElementManifest Location="Elements.xml" />
    </ElementManifests>
</Feature>


Elements.xml:

<?xml version="1.0" encoding="utf-8" ?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
    <Workflow
        Name="Expense Report Workflow"
        Description="desc."
        Id="[Guid]"
        CodeBesideClass="TestInfoPathWorkflow.Workflow1"
        CodeBesideAssembly="TestInfoPathWorkflow, Version=1.0.0.0, Culture=neutral, PublicKeyToken=[TOKEN]"
    >
    </Workflow>
</Elements>

 

5. Replace [Guid] with new, unique Guid

 

6. Replace [Token] with the unique public key token from your workflow

 

Build the project and then drop the assembly into the GAC (c:\windows\assembly). Then, right click on the assembly and click properties. Lastly copy and paste the token:

 

 

Example:

<Workflow
    Name="Expense Report Workflow"
    Description="desc."
    Id="51EE11E4-CC2B-44c6-B599-2D2B25793E95"
    CodeBesideClass="TestInfoPathWorkflow.Workflow1"
    CodeBesideAssembly="TestInfoPathWorkflow, Version=1.0.0.0, Culture=neutral, PublicKeyToken=7ee59b283157fb98"
    >
</Workflow>

 

7. Generate a proxy class off your InfoPath form

 

Within your InfoPath form, click File – Save as Source Files:

 

 

After you specify a location to save the files to, it will spit out a whole lot of stuff:

 

 

What is most special to us is the myschema.xsd file. This file contains the schema for the InfoPath form and will be used to generate our proxy class. To generate the proxy, open Visual Studio tools command prompt:

 

 

And run the following command:

 

 

[If you get an error that is similar to "Error: The process cannot access the file 'c:\users\administrator\desktop\published\myschema.xsd' because it is being used by another process.", you have to close the InfoPath form first. When the form is open, it has a lock on the schema file.]

 

This will spit out a new file called myschema.cs that contains all the properties for the fields in our InfoPath form. We can instantiate this class to get at our form data (more on this in a bit). Add this new class to your Visual Studio project, and then rename the file to whatever the class name is (in my case it's ExpenseReportFields):

 

 

8. Drop the OnWorkflowInstanciated and WorkflowItemChanged activites onto the design surface

 

You should see these activities in the toolbox:

 

 

After you get them on the surface, you'll notice that each has an exclamation point in the upper right had corner of the activity:

 

 

You resolve the error, set a correlation token for each. On the first activity, right click the activity and choose properties. Find the CorrelationToken property and type in a token (this can be any text you want):

 

 

[Note: make sure AFTER you type a token, that you hit the plus sign and specify the OwnerActivityName property]

 

On the second activity, rather than type a new token, select from the dropdown the token you typed in the first activity. Now, both activities will be correlated to one another, and to the same workflow list item. (The red exclamation points should disappear as well)

 

9. Add code to the WorkflowItemChanged activities to handle when the form is edited

 

As was stated, the example being demonstrated is handling whenever an expense report is submitted/edited. The code we're going add in this step will get ran when the form has been edited. It will load the form's XML from it's SPFile object, and then serialize that XML into our proxy object. We will then be able to program against that object with all the data that was entered into the form. To add this code, right click the onWorkflowItemChanged activity and choose Generate Handlers. This will create a method called onWorkflowItemChanged1_Invoked and any code you put in there will run when the form is edited.

 

Copy the following code into the onWorkflowItemChanged1_Invoked method:

 

// Create an SPFile object off the list item – this is our Form
SPFile file = onWorkflowActivated1.WorkflowProperties.Item.File;

// Load the contents of the file into an Xml reader
XmlTextReader reader = new XmlTextReader(file.OpenBinaryStream());
XmlSerializer serializer = new XmlSerializer(typeof(ExpenseReportFields));

// Deserialize the xml content into an instance of our proxy class
ExpenseReportFields fields = (ExpenseReportFields) serializer.Deserialize(reader);

// Do something cool! (I'm just updating a field on the list item, not too cool
L)
file.Item["Money"] = fields.money;
file.Item.Update();

 

10. Deploy and Test!

 

The first thing to do is to build the project and drop it in the GAC (again). This will get the latest code available. Next you need to install and activate our feature. In the Features directory in the 12 Hive, create a new folder (named whatever you want) and copy/paste the Feature.xml and Elements.xml files into the new folder.

 

IISRESET!

 

Then run the InstallFeature STSADM command: stsadm –o installfeature –name foldername

 

 

Now on the site, activate the feature (in my case it's called Expense Report Workflow) and add the workflow to one of your form libraries. To do this, go to form library settings, workflow settings, select the workflow and configure the rest of the settings per your requirements:

 

 

DONE!

 

Now when I start the workflow and edit my form, the code grabs the "money" field out of the form and updates the "Money" column on the SharePoint list. Pretty neat!

 

 

Phil

 
Posted by Phillip S. Wicklund on 20-Feb-09
0  Comment  |  Trackback Url  | 0  Link to this post | Bookmark this post with:        
 
Failed to render control: Value does not fall within the expected range.

Comments

Bookmark and Share

Note: Facebook no longer sends notifications for comments, so it may be a number of days before I see your post. For urgent matters, click "Contact Me" on the top nav. More info: Click Here.