How to Safely Insert a String of Text Into a Biztalk Message
Recently while working on a Biztalk project there was a number of suspended instances that were appearing in the Biztalk Admin Console, after some investigation in to the cause of these suspended instances it was determined that the orchestrations were failing because of uncaught exceptions being thrown from within the orchestration’s exception handlers.
The cause of these uncaught exceptions was eventually tracked down to the following line of code inside of a message construction shape.
xmlExceptionMsg.LoadXml("<ns0:Exception xmlns:ns0='http://Ka.Integrations.ServiceMax.Common.Schemas.ExceptionMessage'><Message>" + SysException.Message.ToString() + "</Message></ns0:Exception>");
To give a little bit of context to the code snippet above, the xmlExceptionMsg object is an orchestration variable of type System.Xml.XmlDocument which is being used to construct a BizTalk message and the LoadXml method is meant to take a string of text which is valid Xml from which that message will be built.
However, it was this method call that was raising the exception that subsequently caused the orchestration to fail.
The issue was being caused when the LoadXml method was being passed an input argument that was not a valid string of XML. The documentation for this method indicates that this type of argument error will raise an exception of type XmlException at runtime. So when seeing this exception type being thrown form an orchestration shape that has within it a LoadXml method call be alerted to the fact that the Xml being loaded is most likely invalid.
The string being loaded in the code snippet above has both some hand written Xml and the contents of the exception object’s message field within it. Both the Xml being written by hand and the contents of the Message field should be inspected for anything that may cause the Xml being loaded to be invalid. In this case it was the Message field that contained an Xml document within it (which can be discovered by printing this field out to the event log for visual inspection) and it was this nesting of two Xml documents that was the root cause of the issue.
Fixing this problem requires only a relatively small change to the code. The SysException.Message field will need to be wrapped inside of a CDATA block to make the Xml contained within it cause no harm when the string is loaded by the LoadXml method. The effect that the CDATA enclosure has on the Xml meta characters contained inside the SysException’s Message field is to rewrite them all using an escape sequence instead.
xmlExceptionMsg.LoadXml("<ns0:Exception xmlns:ns0='http://Ka.Integrations.ServiceMax.Common.Schemas.ExceptionMessage'><Message><![CDATA[" + SysException.Message.ToString() + "]]></Message></ns0:Exception>");