Using Linq in SharePoint InfoPath Code Behind

I’m a huge fan of Linq (in C#, not the chat client Lync which I am also a fan of). It allows me to quickly query an array and manipulate my data SO much faster than loops and datasets.

One of my favorite things to do is to grab an array of items, and create a collection of anonymous objects with just the properties I need. Similar to:

var comps = from XPathNavigator r in compRows
 group r by r.SelectSingleNode("my:CompTitle", NamespaceManager).Value.ToString() into g
 select new
 {
 Title = g.Key,
 Total = g.Sum(c => Convert.ToInt32(c.SelectSingleNode("my:CompsUsed", NamespaceManager).Value.ToString()))
 };

In the above, I just needed a quick array of items which are to be later loaded into a repeating table. This works great through the InfoPath client, and the use of anonymous objects works great everywhere else. It appears the InfoPath Form Services in SharePoint 2013 (I’d be willing to bet 2010 as well) doesn’t like it as much. When I upload the form, it errored and the ULS logs reported:

ConstructFromXsnFile failed with unhandled exception System.NullReferenceException: Object reference not set to an instance of an object. at Microsoft.Office.InfoPath.Server.Converter.DetectUnsupportedNamespaces. VerifyNamespace(String ns, String nodeName, ICollection`1 problems) at ....

Such a helpful error isn’t it? I went ahead, using .Net Reflector, and decompiled and debugged Microsoft.Office.InfoPath.Server.dll. This clarified things a lot. When the InfoPath form is verified, SharePoint checks all of the methods and namespaces, and one check is for anonymous types. There didn’t appear to be an option to override so I updated my code to not use anonymous types.

I created a quick class file with the same properties, and updated my code above by simply changing one line

select new CompTotal

so now my code looks like

var comps = from XPathNavigator r in compRows
 group r by r.SelectSingleNode("my:CompTitle", NamespaceManager).Value.ToString() into g
 select new CompTotal
 {
 Title = g.Key,
 Total = g.Sum(c => Convert.ToInt32(c.SelectSingleNode("my:CompsUsed", NamespaceManager).Value.ToString()))
 };

BLAMO! It worked, and quite well. I hope this helps someone in the future who might be chasing down a similar issue.

Happy SharePointing!

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s