Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Writing an XML fragment using XmlWriterSettings and XmlSerializer is giving an extra character

I need to write an XML fragment to be consumed by a web service. Any xml declarations cause the web service to reject the request. To support this I have the following class:

public class ContentQueryCriteria
{
    public int Type { get; set; }
    public string Value { get; set; }
    public int Condition { get; set; }
}

which allow me to set the request criteria and then get the results.

The code is used like this:

ContentQueryCriteria content = new ContentQueryCriteria();
            content.Type = 1;
            content.Value = "NAVS500";
            content.Condition = 1;

            string requestBody = SerializeToString(content);
            Console.WriteLine(requestBody);

When I serialize this to an XML file I get a proper response, without the XML declaration or any namespaces. However, I would rather capture the data in a memory stream rather then a file.

Using the following method (taken from http://www.codeproject.com/Articles/58287/XML-Serialization-Tips-Tricks ) I am able to achieve results, but for some reason I have a ? listed as part of the string.

public static string SerializeToString(object obj)
{
    XmlSerializer serializer = new XmlSerializer(obj.GetType());
    XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
    ns.Add("", "");

    MemoryStream ms = new MemoryStream();

    XmlWriterSettings settings = new XmlWriterSettings();
    settings.OmitXmlDeclaration = true;
    settings.Encoding = Encoding.Unicode;
    XmlWriter writer = XmlWriter.Create(ms, settings);
    serializer.Serialize(writer, obj, ns);

    return Encoding.Unicode.GetString(ms.ToArray());

} 

the resulting string is:

?<ContentQueryCriteria><Type>1</Type><Value>NAVS500</Value><Condition>1</Condition></ContentQueryCriteria>

if I set OmitXmlDeclaration = false I get the following string:

?<?xml version="1.0" encoding="utf-16"?><ContentQueryCriteria><Type>1</Type><Value>NAVS500</Value><Condition>1</Condition></ContentQueryCriteria>

Can anyone help me determine why the extra ? is there and how I can remove it?

Working SerializeToString method with no BOM

public static string SerializeToString(object obj)
{
    XmlSerializer serializer = new XmlSerializer(obj.GetType());
    XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
    ns.Add("", "");
    MemoryStream ms = new MemoryStream();
    XmlWriterSettings settings = new XmlWriterSettings();
    settings.OmitXmlDeclaration = true;
    settings.Encoding = new UnicodeEncoding(bigEndian: false, byteOrderMark: false);
    XmlWriter writer = XmlWriter.Create(ms, settings);
    serializer.Serialize(writer, obj, ns);

    return Encoding.Unicode.GetString(ms.ToArray());


}
like image 251
Robert H Avatar asked Jul 12 '12 16:07

Robert H


1 Answers

You are seeing BOM (byte order mask) as first character in your string converted from stream's byte array.

Turn off outputting BOM and you'll be fine.

Use encoding object that does not generate BOM: UnicodeEncoding

settings.Encoding = new UnicodeEncoding(bigEndian:false,byteOrderMark:true)
like image 104
Alexei Levenkov Avatar answered Nov 09 '22 21:11

Alexei Levenkov