Exchange does not like Null character (\0) in outgoing email bodies
Last time I was developing for Microsoft Exchange, I was seeing a wierd exception in our application trying to send an email using Exchange (the application uses EWS Managed API to interact with Exchange).
The exception message went something like this when it was shown in the browser:
The invalid value '<p>Test</p>' was specified for the 'Body' element.
'<p>Test</p>' contained the actual email body I was trying to send and it appeared perfectly fine to me. So why would Exchange find this email body invalid.
I was able to find the reason quickly, the email body was ending in a NULL character (\0). And it seems like Exchange does not like NULL characters in email bodies as you can see from the InnerException of the original exception thrown by EWS API:
'.', hexadecimal value 0x00, is an invalid character. at System.Xml.XmlUtf8RawTextWriter.InvalidXmlChar(Int32 ch, Byte* pDst, Boolean entitize) at System.Xml.XmlUtf8RawTextWriter.WriteElementTextBlock(Char* pSrc, Char* pSrcEnd) at System.Xml.XmlUtf8RawTextWriter.WriteString(String text) at System.Xml.XmlWellFormedWriter.WriteValue(String value) at Microsoft.Exchange.WebServices.Data.EwsServiceXmlWriter.WriteValue(String value, String name)
where the outer exception is something like this:
The invalid value '<p>Test</p>\0' was specified for the 'Body' element. at Microsoft.Exchange.WebServices.Data.EwsServiceXmlWriter.WriteValue(String value, String name) at Microsoft.Exchange.WebServices.Data.ComplexProperty.WriteToXml(EwsServiceXmlWriter writer, XmlNamespace xmlNamespace, String xmlElementName) at Microsoft.Exchange.WebServices.Data.ComplexPropertyDefinitionBase.WritePropertyValueToXml(EwsServiceXmlWriter writer, PropertyBag propertyBag, Boolean isUpdateOperation) at Microsoft.Exchange.WebServices.Data.PropertyBag.WriteToXml(EwsServiceXmlWriter writer) at Microsoft.Exchange.WebServices.Data.CreateRequest`2.WriteElementsToXml(EwsServiceXmlWriter writer) at Microsoft.Exchange.WebServices.Data.ServiceRequestBase.WriteBodyToXml(EwsServiceXmlWriter writer) at Microsoft.Exchange.WebServices.Data.ServiceRequestBase.WriteToXml(EwsServiceXmlWriter writer) at Microsoft.Exchange.WebServices.Data.ServiceRequestBase.Emit(HttpWebRequest& request) at Microsoft.Exchange.WebServices.Data.ServiceRequestBase.ValidateAndEmitRequest(HttpWebRequest& request) at Microsoft.Exchange.WebServices.Data.SimpleServiceRequestBase.InternalExecute() at Microsoft.Exchange.WebServices.Data.ExchangeService.InternalCreateItems(IEnumerable`1 items, FolderId parentFolderId, Nullable`1 messageDisposition, Nullable`1 sendInvitationsMode, ServiceErrorHandling errorHandling) at Microsoft.Exchange.WebServices.Data.Item.InternalCreate(FolderId parentFolderId, Nullable`1 messageDisposition, Nullable`1 sendInvitationsMode) at Microsoft.Exchange.WebServices.Data.EmailMessage.InternalSend(FolderId parentFolderId, MessageDisposition messageDisposition) at Microsoft.Exchange.WebServices.Data.EmailMessage.SendAndSaveCopy()
Having found this, the solution was simple; to strip out null charatcer from email body using: body.Trim('\0'); where body was a string containing the email body to be dispatched.
However my next concern was where was the NULL character coming from. The body was being composed in the browser using TinyMCE editor and as far as I knew, TinyMCE does not add that character to the html being composed.
A bit more investigation revealed the source. The body was actually a forwarded message from a PST file. Our application allows browser based PST and Exchange interaction and I was opening a email message from a Pst file using the application and then forwarding it using the Exchange component of the application. And it seemed like the message body stored in Pst was ending in the NULL character which was getting passed through to Exchange when forwarded.
It now appears that the issue actually lies with the Xml handling in .Net rather than with Exchange or EWS API. The same application I am referring to above logs exceptions as xml strings which are parsed back using classes in System.Xml namespace. I went to the Event Log of our application and this time the Event Log threw an exception trying to display the details of the above mentioned exception which was logged in it:
\u0027.\u0027, hexadecimal value 0x00, is an invalid character. Line 1, position 173. at System.Xml.XmlTextReaderImpl.Throw(String res, String args) at System.Xml.XmlTextReaderImpl.ParseText(Int32& startPos, Int32& endPos, Int32& outOrChars) at System.Xml.XmlTextReaderImpl.ParseText()\r\n at System.Xml.XmlTextReaderImpl.ParseElementContent() at System.Xml.Linq.XContainer.ReadContentFrom(XmlReader r) at System.Xml.Linq.XContainer.ReadContentFrom(XmlReader r, LoadOptions o) at System.Xml.Linq.XElement.ReadElementFrom(XmlReader r, LoadOptions o) at System.Xml.Linq.XElement.Load(XmlReader reader, LoadOptions options) at System.Xml.Linq.XElement.Parse(String text, LoadOptions options)
If you compare the stack traces, it becomes fairly obvious System.Xml does not like Null charatcers while reading or writing xml strings.