InfoPath and Web Service data connection

I have used InfoPath mainly with SharePoint and my experiences have been quite good. However I have always felt like something was missing... something that would really warm my developer heart. And I have found it! It's nice integration with Web Services. InfoPath can retrieve and submit data to the Web Services with just few lines of code for Web Service and few button clicks at the InfoPath. But if you're creating serious application you should definitely create XML Schema that is shared with applications. It would be easy to use ready-made schema at the InfoPath and in your other applications as well. I'm just going to create small example that uses web services to get data to few fields at the InfoPath. In my experience it's fairly common that you have a lot of fields at the InfoPath and then you would like to autopopulate some of the fields based on some other fields. You probably want to get your employee/customer/product data from some of the back-end systems like ERP, CRM, etc. So this example demonstrates simple way of achieving that kind of functionality. I'm going to present this development process in "real world scenario". So it means that developer creates web service and UI Designer creates the InfoPath form (Warning! It may contain sarcasm!). But enough talking... Let's start hacking!

1. Create web service to return employee data

First we're going to create simple web service that returns some employee data (and now 'we' stands for person in developer role):

  1: using System;
 2: using System.Web;
 3: using System.Web.Services;
 4: 
 5: public class Service : System.Web.Services.WebService {
 6:     public struct Employee {
 7:         public int EmployeeNumber;
 8:         public String Title;
 9:         public String FirstName;
10:         public String LastName;
11:         public Decimal Salary;
12:     }
13: 
14:     [WebMethod]
15:     public Employee GetEmployee(int employeeNumber) {
16:         Employee employee = new Employee();
17:         employee.EmployeeNumber = employeeNumber;
18:         employee.Title = "Developer";
19:         employee.FirstName = "John";
20:         employee.LastName = "Doe";
21:         employee.Salary = 12345;
22:         return employee;
23:     }
24: }

Of course your data should be retrieved from your favorite back-end system, but I'll just return some dummy data. Okay now we just compile (and deploy if necessary) our web service so it can be used by InfoPath. And copy the WSDL url because you need it later when dealing with the InfoPath form.

2. Create InfoPath form

If I would be really lazy I would use Design a form template -> Web Service since it's really straightforward if you want to retrieve and submit data with Web Services. But I'm just going to take Design a form template -> Blank. Because in many cases the UI designer doesn't know much about programming. Designer just drag & drops the controls to the template and stops working with the template when it looks good (Note: this form is my handwriting so it hasn't even seen any UI design experience :-).

After that designer gives the template to the developer. And developer sees right away that designer didn't think about those pretty important things like schemas and data sources

Developer doesn't want to do any extra work so he just renames the controls so that they're are easily understandable.

After that developer changes the Form Template Properties at the File -> Properties. And now developer is ready to add web service datasource to the InfoPath form.

3. Create Web Service datasource

 Under Tools -> Data Connections add new data connection:

Select Receive data and press Next.

Select Web service and press Next.
 
Paste the url of the WSDL and press Next.

Select GetEmployee method from the list (it's the only one so easy selection :) and press Next.

Take away selection from Automatically retrieve data when form is opened and press Finish.

4. Create Rule to the button that uses the new datasource

Now we have managed to create connection to our web service. Let's add the Rule to the button so that web service is called when user clicks the button. The Rule will contain following phases:

  1. Set parameter for the Web Service Call
  2. Make the Web Service Call
  3. Set field values for each field from the secondary datasource (=Web Service)

Right click on the button and select Properties. Click on the Rules button and then click Add button from the Rules dialog. Write name of this new rule (like Get employee data from Web Service).

Then we need to add some actions to the rule. Just click Add action button:
 
Verify that your checkbox is Set a field's value and then press button next to the Field textbox. Then you can select the employeeNumber from the GetEmployee data source.

After that you do the same for the Value field. That was phase 1.

Phase 2 is really simple... just add new action for Query using a data connection: GetEmployee.

Phase 3 contains quite many button clicks... just create Set a field's value actions for each value return from the Web Service field:

Finally we have following Actions in our Rule:

And now we're ready to test our form. Just press Preview toolbar item. When form opens you can fill Number field with some number and populate the other fields by pressing the Get employee data button:
 
Fields are filled with the retrieved data from the Web Service.

Summary

Now you know howto create simple Web Service call from InfoPath. But you may wonder that how did those field names come from the web service struct into the InfoPath form? Well if you look at the services WSDL you can see, that it contains definitions for the Employee data structure:

So it's really easy to create small struct that contain the necessary datas you want to expose from your service. It's easy and fast, but more correct way would be using the schemas. See Creating a web service for InfoPath from in 25 easy steps article from the links below. And of course posting the data to the web service would be exactly the same as this example. Just create new Rule that first copies all values from the fields in the form to the datasource fields. And after that you just call the correct method from the datasource. Isn't it easy... I think it is.

That was my InfoPath post this time. And maybe next time something completely different stuff :)

Anyways... Happy hacking!

J

Build a Custom SharePoint Web Service for Your InfoPath 2003 Documents 
-- Howto retrieve and submit data with XmlDocument

Creating a web service for an InfoPath form in 25 easy steps 
-- Creates InfoPath form and then extracts XML Schema out of it (Note: Exporting source files in InfoPath 2007: File->Save as Source Files). Then xsd.exe is used to create .cs -file. It's then added to Visual Studio and used when creating the web service. And developer can enjoy full support from IntelliSense .

Querying and Updating a Database Using Web Services in InfoPath and ASP.NET 
-- Example that uses DataSets with InfoPath.