Skip to main content

Haylee Fox

Go Search
Haylee Fox
About Me
Speaking Events
Demos
Downloads
  
 

Updating where an InfoPath form is looking for the Data Connections – without having to recreate them

I'm using UDCX's in my InfoPath forms and have previously written a post on ho to programmatically update them. But you still need to update the Location in the InfoPath form. So I thought I'd do a quick post of how to do this without having to delete them and recreate them as this also removes any filtering and binding etc.

Essentially, what you need to do is extract the files from .xsn, modify manifest.xsf and repackage as cab file then rename back to a .xsn. I found the best cab maker to use is PowerArchiver. It's got a nice user interface and is easy to use.

 

  1. Using any extraction software (7zip, WinZip, PowerArchiver etc)
  2. Right Click on manifest.xsf and select Open With, then select Notepad

  3. Click Edit and Select Replace

  4. In the Find and Replace dialog box, Enter the older URL in find and enter the url to the new Site collection in replace, then click Replace All

  5. Click File and Save

  6. Open PowerArchiver
  7. Click New Archive

  8. In the New Archive Dialog Box navigate to where you want to save the Form, Enter a file name Select .CAB in the Save as Type. Then click Save

  9. In the Add dialog box, change the location to where you originally extracted the .xsn, then select all files and click Add

  10. Close PowerArchiver
  11. Navigate to where you saved the cab right click the cab file and select Rename change the file extension from .cab to .xsn then click enter, click Yes on the renamed extension warning.
  12. Right Click the form and Select Design
  13. In the Ribbon Click the Quick Publish Icon

  14. In the Save Form Dialog box, Select a suitable location to save the form and click OK
  15. When the form has been successfully published, click ok.

The form will now be published to the new location, using all of the udcx's in the new site collection.

Making InfoPath Data Connections Deployable

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" ?>

<Elements xmlns="http://schemas.microsoft.com/sharepoint/">

<ListInstance

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"/>

</Elements>

 

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"?>

<?MicrosoftWindowsSharePointServices ContentTypeID="0x010100B4CBD48E029A4ad8B62CB0E41868F2B0"?>

<udc:DataSource MajorVersion="2" MinorVersion="0" xmlns:udc="http://schemas.microsoft.com/office/infopath/2006/udc">

<udc:Name>UDCX Display Name</udc:Name>

<udc:Description/>

<udc:Type MajorVersion="2" MinorVersion="0" Type="SharePointList">

<udc:SubType MajorVersion="0" MinorVersion="0" Type=""/>

</udc:Type>

<udc:ConnectionInfo Purpose="ReadOnly" AltDataSource="">

<udc:WsdlUrl/>

<udc:SelectCommand>

<udc:ListId/>

<udc:WebUrl/>

<udc:ConnectionString/>

<udc:ServiceUrl UseFormsServiceProxy="false"/>

<udc:SoapAction/>

<udc:Query/>

</udc:SelectCommand>

<udc:UpdateCommand>

<udc:ServiceUrl UseFormsServiceProxy="false"/>

<udc:SoapAction/>

<udc:Submit/>

<udc:FileName>Specify a filename or formula</udc:FileName>

<udc:FolderName AllowOverwrite=""/>

</udc:UpdateCommand>

</udc:ConnectionInfo>

</udc:DataSource>

 

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" ?>

<Elements xmlns="http://schemas.microsoft.com/sharepoint/">

<Module Name="DataConnections" Url="DataConnections" Path="">

<File Url="LibraryDisplayName.udcx" Type="GhostableInLibrary" IgnoreIfAlreadyExists="FALSE">

<Property Name="Title" Value="Library Display Name.udcx"></Property>

</File>

</Module>

</Elements>

 

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!)

using System;

using System.Collections.Generic;

using System.Xml;

using System.Text;

using System.Globalization;

using Microsoft.SharePoint;

using Microsoft.SharePoint.Administration;

 

namespace InfopathDataConnections.EventHandlers.Features

{

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")

{

UpdateDataConnectionLibrary(item);

}

}

 

}

 

private void UpdateDataConnectionLibrary(SPListItem item)

{

 

 

XmlDocument doc = new XmlDocument();

using (System.IO.Stream stream = item.File.OpenBinaryStream())

{

doc.Load(stream);

}

 

XmlNamespaceManager nameSpaceManager = new XmlNamespaceManager(doc.NameTable);

nameSpaceManager.AddNamespace("udc", "http://schemas.microsoft.com/office/infopath/2006/udc");

 

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.SaveBinary(encoding.GetBytes(doc.InnerXml));

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.

J

 

Programmatically create an External list in a feature from existing External Content Type – getting the required properties

Creating the list is fairly straight forward. Below is the code snippet that is needed in the feature

 

The top section is the same as any List instance. In the case of an external List we need

Type: 600 - but also can be found in the feature directory

Feature ID: 00bfea71-de22-43b2-a848-c05709900100 – also found in the features directory

 

The Datasource section is where we can tell the External List what External Content Type to connect to. In my case,

I'm connecting to an External Content Type that was already created using SharePoint Designer.

You can get the values need by exporting the External Content Type from SharePoint Designer.

Then open the resulting .BDCM file (which is really just an xml file) in either Visual Studio or Notepad (or other program you're comfortable with)

First one you'll see is the LobSystemInstance (to find it quicker just search for LobSystemInstance)

Next Up is the Entity NameSpace and Name

 

The last piece of info we need is the SpecificFinder

 

Putting this together means my code would look like:

Where is the Site Assets library?

Ever wondered about why site Assets is on some sites but not all?  I’ve heard speculation that it’s hidden.  Well nope it’s just not there.  It’s created through the activation of the Wiki home page feature. Go figure huh.

 

What’s even stranger is that if you open a site that doesn’t have a site assets in SharePoint  Designer it will still have the Site Assets library listed there.  You click on it, it’ll think about it for a bit and go ahead and create the library for you on the site.

Creating Tabs on Document Libraries and Lists in SharePoint

This is one of the Demo's I've been showing in my presentation during the various SharePoint Saturday's I've presented at. It's one of my favourites for a number of reason, but mostly because of the endless possibilities. 

 

The Demo can be seen here 

 

The Scenario I’m using is filtering a document library based on the Project.  To set this up I’ve created a Projects list (from custom list)  and a Document Library with a field called Project, which is a look up to my Project List. Obviously this is a very common thing to do in SharePoint. 

 

I’m using JQuery and SP Services (available from Codeplex) to call the Lists web Service and returning all of the Item in the Projects Lists and displaying them as tabs on the page.

 

These tabs are clickable and when clicked recall the Lists Web Serices, but this time, they are sending though the title of the tab to build a caml query that the Web Service uses to only return the items in the Document Library that matches the Query.

 

Very Cool Stuff!

Creating a REST Connection

For those who, like myself, have just started using SharePoint 2010 after using designer 2007 for a couple years will soon try to create a data view using information from a list or library on a different site and find there is no option to add another library, and hence you can no longer add a library from another site in your data sources the way you used to.

The good news is you still can. It's just done a different way. You can either use a SOAP connection or a REST Connection. While REST (Representational State Transfer) isn't new technology it is new to SharePoint and for those that want more information on it check out the wiki article here.

In this post I'm going to show how to set up a simple REST Connection to use as a data source in a data view web part.

Start by opening you site in SharePoint designer 2010

After your site, select Data Sources from the Navigation plane on the left hand side

The select REST Service Connection from the Ribbon at the top

In the Data Source Properties select the Source tab.

Enter the URL in the format

http://<host header>/ _vti_bin/listdata.svc/<list to connect to>

where <host header> is the host header of the site you are accessing, you will need to add /<site name>/ if you are connecting to a site not at the root (ie your url would become header>/<site name>/_vti_bin/listsdata.svc/<list name>

_vti_bin/listdata.svc is the location of the server side scripts to read the list information

<list to connect to> is the name of the list you are accessing.

Couple of things to note here:

  1. To get the iURL of the list http:<host header>/_ vti_bin/listdata.svc into a browser and that will return all of the lists and libraries on that site. You can get all of the information you need from here.
  2. The list name is case sensitive and will not work if you have incorrect case.

 

Depending on your set up you may also need to configure the permissions in the Permissions tab.  If you don't set up permissions you may get an error when you try to use the data connection.  If you see the error check your permissions tab

This will now add the data sources to your available data sources and you'll be able to create data views with information from different sites just like you used to in Designer 2007.

So far I have come across a couple of limitations.  Mostly around lookup lists and the way the inforamtion is stored, for example the only information is the ID of the item that is being looked up therefore you can't display the title of that item in your dataview.