Use a custom SharePoint workflow to extract a file attachment from an InfoPath form and upload it to a SharePoint document library

by S.Y.M. Wong-A-Ton

This article explains how you can use a custom Visual Studio sequential workflow on a Form Library to extract data from a File Attachment control on an InfoPath form that was submitted to the Form Library and use this data to add a file to a SharePoint Document Library.

Problem

You want to extract and upload a document that is stored as a File Attachment in an InfoPath form to a SharePoint document library when the InfoPath form is submitted to or saved in a Form Library.

Solution

You could use either an ItemAdded SharePoint event handler or a custom Visual Studio workflow for SharePoint to extract and upload a document stored as a file attachment in an InfoPath form to a SharePoint document library.

This article discusses the second method.

Discussion

This article assumes that you have created an InfoPath form template that has a File Attachment control named attachment, and published the InfoPath form template to a SharePoint Form Library.

This article also assumes that you have created a Document Library named Form Attachments in SharePoint and that you know how to work with and program in Microsoft Visual Studio.

You can create the custom Visual Studio workflow as follows:

  1. In Microsoft Visual Studio 2005, from the File menu, choose New, and then Project.
  2. On the New Project dialog box, click the SharePoint project type, select the Sequential Workflow Library template if you're using WSS or the SharePoint Server Sequential Workflow Library template if you're using MOSS, name the project ExtractAttachmentInfoPathForm (or whatever you like), and click OK.
  3. Add a Code activity to the Sequential Workflow as shown in figure 1.
    Sequential workflow in Microsoft Visual Studio 2005
    Figure 1. Sequential workflow in Microsoft Visual Studio 2005.
  4. Add the following namespaces to the Workflow1.cs file:

    using System.Collections.Generic;
    using System.Xml.XPath;
    using System.IO;
    using System.Text;

  5. In the Workflow Designer, right-click onWorkflowActivated1 and select Generate Handlers from the context menu.
  6. Add the following C# code to the onWorkflowActivated1_Invoked event handler:

    workflowId = this.workflowProperties.WorkflowId;

  7. In the Workflow Designer, right-click codeActivity1 and select Generate Handlers from the context menu.
  8. Add the following C# code to the codeActivity1_ExecuteCode event handler:

    // Retrieve the file associated with the item
    // on which the workflow has been instantiated
    SPFile file = workflowProperties.Item.File;

    if (file == null)
    return;

    // Get the binary data of the file
    byte[] xmlFormData = null;
    xmlFormData = file.OpenBinary();

    // Load the data into an XPathDocument object
    XPathDocument ipForm = null;

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

    if (ipForm == null)
    return;

    // Create an XPathNavigator object to navigate the XML
    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 attachment in the InfoPath form
    XPathNavigator nodeNav = ipFormNav.SelectSingleNode(
    "//my:attachment", nsManager);

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

    // Decode the InfoPath file attachment
    InfoPathAttachmentDecoder dec =
    new InfoPathAttachmentDecoder(ipFieldValue);
    string fileName = dec.Filename;
    byte[] data = dec.DecodedAttachment;

    // Add the file to a document library
    using (SPWeb web = workflowProperties.Web)
    {
    SPFolder docLib = web.Folders["Form Attachments"];
    docLib.Files.Add(fileName, data);
    }
    }

    Note: This code makes use of the InfoPathAttachmentDecoder class described in How to encode and decode a file attachment programmatically by using Visual C# in InfoPath.

  9. In the Solution Explorer, right-click the project, and select Properties.
  10. Click the Signing tab and sign the assembly with a strong name key file.
  11. Build the project and register the resulting DLL in the Global Assembly Cache (GAC).
  12. Open the feature.xml file and follow the instructions to add the appropriate XML snippet.
  13. Open the workflow.xml file and follow the instructions to add the appropriate XML snippet.
  14. Open the install.bat file and follow the instructions.
  15. Run the install.bat file to install and activate the feature for the workflow.
  16. In SharePoint, go to the Form Library on which you want the workflow to run, click Settings, and select Form Library Settings.
  17. On the Form Library Settings page, click Workflow settings.
  18. On the Add a Workflow page, select your workflow from the workflow template list box, enter a name for your workflow, select the Start this workflow when a new item is created check box, and click OK.

If you're unsure how to create and deploy a Visual Studio workflow for SharePoint, see Visual Studio Workflows for SharePoint Mini Course.

Now whenever you fill out a new InfoPath form, attach a document or file to it, and submit it to the form library, the workflow on the InfoPath form is started, and the document or file you attached to the InfoPath form is extracted and uploaded to the Form Attachments SharePoint document library.

Related InfoPath Articles:

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. Usage of 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.

Working with InfoPath