Search code examples
c#xmlexception.net-3.5xelement

XElement.Save causes XmlUtf8RawTextWriter to throw an exception


The following exception was reported to have occurred on a client's machine:

System.ArgumentException: '', hexadecimal value 0x1F, 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.XmlUtf8RawTextWriterIndent.WriteString(String text)
at System.Xml.XmlWellFormedWriter.WriteString(String text)
at System.Xml.Linq.ElementWriter.WriteElement(XElement e)
at System.Xml.Linq.XElement.WriteTo(XmlWriter writer)
at System.Xml.Linq.XElement.Save(XmlWriter writer)
at System.Xml.Linq.XElement.Save(String fileName, SaveOptions options)
at System.Xml.Linq.XElement.Save(String fileName) 

Unfortunately, no more information is available.

The error is a bit baffling.

0x1F is a question mark. If a question mark was included in the name of some element or attribute (which is illegal), an exception would be thrown at creating an XElement or an XAttribute with an invalid name rather than at the moment of saving to disk.

The exception was thrown by XmlUtf8RawTextWriter class which is what XElement uses internally I guess (the application doesn't). Can't XElement be expected to handle coding issues etc. by itself? What could have caused it to crash? Is it some OS or framework incompatibility?

I understand my question is rather vague, but I must operate on limited information.

I'd appreciate if someone could at least point me in right direction. I haven't seen an error like this before.


Solution

  • U+001F isn't actually a question mark - it's a control character ("information separator one") which isn't permitted in XML. (U+003F is a question mark.)

    Basically you've got an invalid character in your XElement, which can't be correctly persisted. It's not clear where you're getting your data from, but that's the problem. You'll need to work out what to do with the bad data - whether to just remove it entirely, escape it somehow or whatever.

    Here's a short but complete program which will reproduce the problem though, if it helps:

    using System;
    using System.IO;
    using System.Xml.Linq;
    
    class Test
    {
        static void Main()
        {
            var element = new XElement("foo", "\u001f");
            element.Save(new MemoryStream());
        }
    }