K2 SmartObject Event - InfoPath XmlFields bug

So, this is the first time that I’m blogging about a K2 problem I’ve had for a while… At work we have a nice mail and registration process and with the new K2 BlackPearl we’d like to be able to design the process with “nice” InfoPath forms (since they are easy to create).

K2 BlackPearl has some great integration with InfoPath, SharePoint and SmartObjects. The Mail and Registration process is quite simple. It gets triggered when a document is placed inside an Document Library. The process then creates a SmartObject to store metadata of the document (like a URL and name of the document). The next step is to show the user a infopath form to add extra data, including a link to the document that has been uploaded to the document library.

Now there’s a small problem, the infopath form needs a reference (the SmartObject ID) to the SmartObject to load that data, unfortunately you aren’t able to put return values from a smartobject directly into the XmlField of the InfoPath form without using code. The XmlField is the XML representation used by the K2 process for the infopath form, so changing the XmlField values changes the content of the infopath form associated to the process.

A SmartObject Event would be used to create the SmartObject with metadata and then store the returned SmartObject ID into the XmlFields. The SmartObject event probably has a small bug (already reported) which makes it unable to use the InfoPath XmlFields.

To fix this, you can store the return value of the SmartObject in a process DataField and in a server/code event put that into the Xmlfield. The code looks something like this:

XmlDocument xmlDoc = new XmlDocument();  
xmlDoc.LoadXml(K2.ProcessInstance.XmlFields[“ECMInput”].Value);  
xmlDoc.PreserveWhitespace = true;
 
XmlNode xmlnode = xmlDoc.GetElementsByTagName(“my:ECMMetaDataID”)[0];  
xmlnode.InnerText = Convert.ToString(((long)K2.ProcessInstance.DataFields[“MetaDataID”].Value));
 
K2.ProcessInstance.XmlFields[“ECMInput”].Value = xmlDoc.OuterXml;

The first few lines just load the XmlField named ECMInput into an XmlDocument. Then we get the node that we want to change (GetElementByTagname(“my:ECMMetaDataID”)[0]) and we start to alter the data. The DataFields[].Value returns a object, and we defined it as long, so there’s a cast, and then a Convert.ToString() to get it to go into the InnerText property of the xmlNode. After that we just load the XmlDoc back into the XmlField. Btw, the PreserveWhitespace is required for InfoPath to work properly with digital signatures!

So, that’s basicly it, a small piece of code to get it all together!