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!
Leave a Reply