How to use a SharePoint ItemAdded event handler and the object model to submit data from an InfoPath form to a SharePoint list

This article explains how you can use an ItemAdded event handler on a Form Library to extract data from an InfoPath form that was submitted to the form library and use this data to add a new item to a custom SharePoint list.

ADVERTISEMENTS

Problem

You want to save the data that is entered into an InfoPath form to a SharePoint list, but InfoPath does not allow you to submit data to a SharePoint list.

Solution

You could use one of the following 5 methods:

  1. Use the SharePoint Lists web service together with a CAML batch update to add an item to a SharePoint list.
  2. Use a SharePoint Designer workflow to get data from the InfoPath form and create a SharePoint list item.
  3. When using an InfoPath browser form, call directly into the SharePoint object model from within the InfoPath form to add an item to the SharePoint list.
  4. Use a SharePoint event handler feature to make calls directly into the SharePoint object model to add an item to the SharePoint list when an InfoPath form is added to a Form Library on which the event handler has been activated.
  5. Use a custom Visual Studio workflow to add an item to the SharePoint list when an InfoPath form is added to a Form Library on which the workflow has been set to run.

This article discusses method 4.

Discussion

In the following example, an InfoPath form with one text field is used to submit data to a custom SharePoint list named Fruits that exists on the same site as where the form library to which the InfoPath form is submitted is located, and populate the Title column of the list with the data from the text box in InfoPath.

The following technique enables you to kick off a SharePoint event handler whenever an InfoPath form is submitted to a form library. In addition, it enables you to retrieve data from the InfoPath form that was submitted and then do whatever you like to do with that data, in this case, use the data from the InfoPath form to create a new item in a SharePoint list.

  1. In InfoPath, create a new Blank browser-compatible form template.
  2. Add a Text Box control (field1) and a Button control to the InfoPath form template.
  3. Double-click the button to open its Properties dialog box.
  4. On the Button Properties dialog box, click Rules.
  5. On the Rules dialog box, click Add.
  6. On the Rule dialog box, click Add Action.
  7. On the Action dialog box, select Submit using a data connection from the Action drop-down list box, and click Add.
  8. On the Data Connection Wizard dialog box, select Create a new connection to, and click Next.
  9. On the Data Connection Wizard dialog box, select To a document library on a SharePoint site, and click Next.
  10. On the Data Connection Wizard dialog box, type in the location for the Document library (in the format http://Server/Site/FormLibrary/), and click the button behind the File name text box.
  11. On the Insert Formula dialog box, type now(), and click OK.
  12. On the Data Connection Wizard dialog box, select the Allow overwrite if file exists check box, and click Next.
  13. On the Data Connection Wizard dialog box, click Finish.
  14. Click OK on all open dialog boxes to close them.
  15. Open Microsoft Visual Studio and follow the instructions on MSDN to create an event handler feature, but override the ItemAdded method instead of the ItemDeleting method.
  16. Add using or Imports statements to the following namespaces:
    • System.Xml
    • System.Xml.XPath
    • System.IO
  17. Add the following C# code to the ItemAdded event handler:

    // Retrieve the InfoPath form that was just added
    byte[] xmlFormData = null;
    SPFile file = properties.ListItem.File;
    xmlFormData = file.OpenBinary();

    XPathDocument ipForm = null;
    if (xmlFormData != null)
    {
    using (MemoryStream ms = new MemoryStream(xmlFormData))
    {
    ipForm = new XPathDocument(ms);
    ms.Close();
    }
    }

    // Populate a namespace manager with the namespaces
    // for the InfoPath form
    XPathNavigator ipFormNav = ipForm.CreateNavigator();

    ipFormNav.MoveToFollowing(XPathNodeType.Element);
    XmlNamespaceManager nsManager =
    new XmlNamespaceManager(new NameTable());

    foreach (KeyValuePair<string, string> ns
    in ipFormNav.GetNamespacesInScope(XmlNamespaceScope.All))
    {
    if (ns.Key == String.Empty)
    {
    nsManager.AddNamespace("def", ns.Value);
    }
    else
    {
    nsManager.AddNamespace(ns.Key, ns.Value);
    }
    }

    // Retrieve the value of the field in the InfoPath form
    XPathNavigator nodeNav = ipFormNav.SelectSingleNode(
    "//my:field1", nsManager);

    string ipFieldValue = string.Empty;
    if (nodeNav != null)
    {
    ipFieldValue = nodeNav.Value;

    // Add an item to a list and use the value of the field
    // as the title for the new item
    if (!String.IsNullOrEmpty(ipFieldValue))
    {
    using (SPSite site = new SPSite(properties.SiteId))
    {
    using (SPWeb web = site.OpenWeb(
    properties.RelativeWebUrl))
    {
    SPList list = web.GetList(
    properties.RelativeWebUrl +
    "/Lists/Fruits");

    if (list != null)
    {
    SPListItem item = list.Items.Add();
    item["Title"] = ipFieldValue;
    item.Update();
    }

    web.Close();
    }

    site.Close();
    }
    }
    }

    If you are writing Visual Basic code, the complete code for the class would look something like the following:

    Imports Microsoft.SharePoint
    Imports System.Xml
    Imports System.Xml.XPath
    Imports System.IO

    Public Class AddedActionVB
    Inherits SPItemEventReceiver

    Public Overrides Sub ItemAdded( _
    ByVal properties As Microsoft.SharePoint.SPItemEventProperties)
    MyBase.ItemAdded(properties)

    ' Retrieve the InfoPath form that was just added
    Dim xmlFormData As Byte() = Nothing
    Dim file As SPFile = properties.ListItem.File
    xmlFormData = file.OpenBinary()

    Dim ipForm As XPathDocument = Nothing
    If xmlFormData IsNot Nothing Then

    Using ms As MemoryStream = New MemoryStream(xmlFormData)
    ipForm = New XPathDocument(ms)
    ms.Close()
    End Using
    End If

    ' Populate a namespace manager with the namespaces
    ' for the InfoPath form
    Dim ipFormNav As XPathNavigator = ipForm.CreateNavigator()

    ipFormNav.MoveToFollowing(XPathNodeType.Element)
    Dim nsManager As XmlNamespaceManager = _
    New XmlNamespaceManager(New NameTable())

    For Each ns As KeyValuePair(Of String, String) _
    In ipFormNav.GetNamespacesInScope(XmlNamespaceScope.All)
    If ns.Key = String.Empty Then
    nsManager.AddNamespace("def", ns.Value)
    Else
    nsManager.AddNamespace(ns.Key, ns.Value)
    End If
    Next

    ' Retrieve the value of the field in the InfoPath form
    Dim nodeNav As XPathNavigator = ipFormNav.SelectSingleNode( _
    "//my:field1", nsManager)

    Dim ipFieldValue As String = String.Empty
    If nodeNav IsNot Nothing Then

    ipFieldValue = nodeNav.Value

    ' Add an item to a list and use the value of the field
    ' as the title for the new item
    If Not String.IsNullOrEmpty(ipFieldValue) Then

    Using site As SPSite = New SPSite(properties.SiteId)

    Using web As SPWeb = site.OpenWeb( _
    properties.RelativeWebUrl)

    Dim list As SPList = web.GetList( _
    properties.RelativeWebUrl & _
    "/Lists/Fruits")

    If list IsNot Nothing Then
    Dim item As SPListItem = list.Items.Add()
    item("Title") = ipFieldValue
    item.Update()
    End If

    web.Close()

    End Using

    site.Close()

    End Using

    End If

    End If

    End Sub

    End Class
  18. Build the project, deploy the event handler feature, and activate the feature to the site where the form library is located.

    Note: You can use a ListTemplateId of 115 in the Elements.xml file to have the event handler feature run on an XML Form Library.

    Contents of the Feature.xml file:

    <Feature Scope="Web"
    Title="ItemAdded Event Handler VB"
    Id="C082C073-D797-4277-8595-8D57B5A306C4"
    xmlns="http://schemas.microsoft.com/sharepoint/">
    <ElementManifests>
    <ElementManifest Location="Elements.xml"/>
    </ElementManifests>
    </Feature>

    Contents of the Elements.xml file:

    <Elements xmlns="http://schemas.microsoft.com/sharepoint/">
    <Receivers ListTemplateId="115">
    <Receiver>
    <Name>ItemAddedEventHandlerVB</Name>
    <Type>ItemAdded</Type>
    <SequenceNumber>10000</SequenceNumber>
    <Assembly>ItemAddedEventHandlerVB, Version=1.0.0.0, Culture=neutral, PublicKeyToken=3470b8ecafe2f4d7</Assembly>
    <Class>ItemAddedEventHandlerVB.AddedActionVB</Class>
    <Data></Data>
    <Filter></Filter>
    </Receiver>
    </Receivers>
    </Elements>

    Contents of an install.bat batch file to install and activate the event handler feature:

    "C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\BIN\stsadm.exe" -o installfeature -filename ItemAddedEventHandlerVB\Feature.xml
    "C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\BIN\stsadm.exe" -o activatefeature -filename ItemAddedEventHandlerVB\Feature.xml -url http://Server/Site
    iisreset

You should now have a fully functional solution so that when you fill out the InfoPath form and click the button, the form is submitted to the form library, and then the event handler is kicked off to add a new item to the SharePoint list with a Title that is the same as the text that you entered into the text box on the InfoPath form.

This technique can be used with any code you would like to execute once an InfoPath form has been submitted to the form library. You do not have to limit yourself to adding items to SharePoint lists, but could for example use the data stored within the InfoPath form to send out an email, call a web service, or add a row to a database table. The possibilities are endless.

 
 Subscribe for updates via RSS or Email

Copyright: This article may not be used on web sites (whether personal or otherwise), copied, disseminated, altered, printed, published, broadcasted, or reproduced in any way without an expressed written consent of S.Y.M. Wong-A-Ton. The techniques demonstrated in this article may be used within any Microsoft InfoPath project. This article is provided without any warranties. Copyright for this article is non-transferrable and remains with the author, S.Y.M. Wong-A-Ton.

InfoPath 2013 Cookbook: 121 Codeless Recipes for Beginners
InfoPath 2013 Cookbook 2: 121 Codeless Recipes for SharePoint 2013
InfoPath 2010 Cookbook: 101 Codeless Recipes for Beginners
InfoPath 2010 Cookbook 2: 101 Codeless Recipes for SharePoint 2010
InfoPath 2010 Cookbook 3: 101 Code Recipes for C# Developers
InfoPath 2010 Cookbook 5: Integrating InfoPath with Excel and Excel Services


Related InfoPath Articles:

ADVERTISEMENTS

InfoPath 2013 Cookbook: 121 Codeless Recipes for Beginners

InfoPath 2013 Cookbook 2: 121 Codeless Recipes for SharePoint 2013

InfoPath 2010 Cookbook: 101 Codeless Recipes for Beginners

InfoPath 2010 Cookbook 2: 101 Codeless Recipes for SharePoint 2010

InfoPath 2010 Cookbook 3: 101 Code Recipes for C# Developers

InfoPath 2010 Cookbook 4: 101 Code Recipes for VB Developers

InfoPath 2010 Cookbook 5: Integrating InfoPath with Excel and Excel Services