Lately I've been putting together a solution that involves some InfoPath forms. I love InfoPath for what it is, but let's face it, it can be a bit painful. One of the biggest pain points is that it's not easily deployable. This is mostly due to the udcx having a reference to the guid of the list they were created on.
I've read a few articles saying that you can simply change the guid to the list name. This didn't work for me so I've come up with a different way to do it which I thought I'd share.
Essentially I'm using 3 features, the first one to deploy the Data connection list instance and the list that the UDCX will connect to, the second to deploy all of the udcx's I'll need, and then the third loops through them and updates the guid and the web URL.
Let's look at it in details. I'm using WSPBuilder (downloadable from codeplex.com) and suggest others do as well.
The first step is to create a new project. Open up Visual Studio create a WSPBuilder Project
Next we need to create our first feature for the List Instances.
Right click your solution and select Add, New Item
Then Select WSPBuilder, Blank Feature, make sure you give it a name then click OK
Scope your feature to Web, and un-tick Event Handler Click finish
The following goes in the elements.xml
<?xml version="1.0" encoding="utf-8" ?>
FeatureId = "00BFEA71-DBD7-4F72-B8CB-DA7AC0440130"
Hidden = "False"
OnQuickLaunch = "False"
RootWebOnly = "TRUE"
TemplateType = "130"
Title = "Data Connections"
Url = "DataConnections"
Description="Library to store Data Connections"
VersioningEnabled = "FALSE"/>
Note: The above will add a Data Connections Library, you can also add other list instances to this feature for example the list or library the UDCX will connect to.
So that's step One, we have a data connections library to hold the UDCX's.
Step Two, we need some UDCX's
Create another feature –using the same steps as above, scope it at a web level, again un-tick Event Handler.
Once it's created, right click your new feature folder and select Add, New Item
Create a new XML file. This File MUST have the same name as the library that it will be connected to and the extension needs to be .udcx (see image below for example)
The following goes in the .udcx
<?xml version="1.0" encoding="UTF-8"?>
<udc:DataSource MajorVersion="2" MinorVersion="0" xmlns:udc="http://schemas.microsoft.com/office/infopath/2006/udc">
<udc:Name>UDCX Display Name</udc:Name>
<udc:Type MajorVersion="2" MinorVersion="0" Type="SharePointList">
<udc:SubType MajorVersion="0" MinorVersion="0" Type=""/>
<udc:ConnectionInfo Purpose="ReadOnly" AltDataSource="">
<udc:FileName>Specify a filename or formula</udc:FileName>
Basically, it's an emply UDCX. You can change the display name and the description. Go ahead and create as many empty UDCX files that you need. Remember they need to be named ListDisplayName.udcx
Next we need to tell the feature to deploy them to the data connection library.
This is done with a module. The following goes into the Elements file of the UDCX feature
<?xml version="1.0" encoding="utf-8" ?>
<Module Name="DataConnections" Url="DataConnections" Path="">
<File Url="LibraryDisplayName.udcx" Type="GhostableInLibrary" IgnoreIfAlreadyExists="FALSE">
<Property Name="Title" Value="Library Display Name.udcx"></Property>
Add a File element for each of the UDCXs that you need to deploy.
OK, we now have a populated Data Connection Library. We now need to update those empty UDCX's with the right information.
Create another feature – using the same method as above, this time scope it to Web and leave the Event Handler ticked. WSPBuilder will automatically create a feature Receiver for this feature, and tell feature to use it. In the feature receiver add the following code (be sure to update your namespace and class to match your feature!)
public class UpdateUDCXReceiver : SPFeatureReceiver
const string DataConnectionsLibrary = "Data Connections";
const string ListIdXPath = "/udc:DataSource/udc:ConnectionInfo/udc:SelectCommand/udc:ListId";
const string weburlXPath = "/udc:DataSource/udc:ConnectionInfo/udc:SelectCommand/udc:WebUrl";
public override void FeatureActivated(SPFeatureReceiverProperties properties)
SPWeb web = (SPWeb)properties.Feature.Parent;
foreach (SPListItem item in web.Lists[DataConnectionsLibrary].Items)
if (item.DisplayName != "Main Submit")
private void UpdateDataConnectionLibrary(SPListItem item)
XmlDocument doc = new XmlDocument();
using (System.IO.Stream stream = item.File.OpenBinaryStream())
XmlNamespaceManager nameSpaceManager = new XmlNamespaceManager(doc.NameTable);
XmlElement root = doc.DocumentElement;
XmlNode folderName = root.SelectSingleNode(ListIdXPath, nameSpaceManager);
SPList locationsList = item.Web.Lists[item.DisplayName]; // GetList(item.Web.Url + "/Lists/" + item.DisplayName);
folderName.InnerText = locationsList.ID.ToString("b");
XmlNode weburlfolder = root.SelectSingleNode(weburlXPath, nameSpaceManager);
weburlfolder.InnerText = item.Web.Url.ToString();
System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
item.File.Approve("Guid and WebUrl Added");
The above code firstly checks to make sure the ucx is not a Main Submit as we don't want to try to change those. It them looks for a List or Library on the current site with the same name as the udcx file and grabs the guid and puts it and the current web into the relevant areas of the udcx. It then approves the udcx so it is usable.
NOTE: you may need to change the target framework to .NET 3.5 - to do this, go to project Properties (right click your project) select the applications tab, change the Target Framework to .NET Framework 3.5 (rebuild if required)
That's it, it should all work. If you'd like to see an example, there is one over on my Downloads page or click here.