<p>I've run into a few gotchas when doing C# XML serialization
that I thought I'd share:</p>

<ul>
<li>You can't serialize items that are read-only (like KeyValuePairs)</li>
<li>You can't serialize a generic dictionary. Instead, try this wrapper class (from <a href="http://weblogs.asp.net/pwelter34/archive/2006/05/03/444961.aspx" rel="noreferrer">http://weblogs.asp.net/pwelter34/archive/2006/05/03/444961.aspx</a>):</li>
</ul>

<hr/>

<pre><code>using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;

[XmlRoot("dictionary")]
public class SerializableDictionary&lt;TKey, TValue&gt; : Dictionary&lt;TKey, TValue&gt;, IXmlSerializable
{      
    public System.Xml.Schema.XmlSchema GetSchema()
    {
        return null;
    }

    public void ReadXml(System.Xml.XmlReader reader)
    {
        XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));
        XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue));

        bool wasEmpty = reader.IsEmptyElement;
        reader.Read();

        if (wasEmpty)
            return;

        while (reader.NodeType != System.Xml.XmlNodeType.EndElement)
        {
            reader.ReadStartElement("item");

            reader.ReadStartElement("key");
            TKey key = (TKey)keySerializer.Deserialize(reader);
            reader.ReadEndElement();

            reader.ReadStartElement("value");
            TValue value = (TValue)valueSerializer.Deserialize(reader);
            reader.ReadEndElement();

            this.Add(key, value);

            reader.ReadEndElement();
            reader.MoveToContent();
        }
        reader.ReadEndElement();
    }

    public void WriteXml(System.Xml.XmlWriter writer)
    {
        XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));
        XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue));

        foreach (TKey key in this.Keys)
        {
            writer.WriteStartElement("item");

            writer.WriteStartElement("key");
            keySerializer.Serialize(writer, key);
            writer.WriteEndElement();

            writer.WriteStartElement("value");
            TValue value = this[key];
            valueSerializer.Serialize(writer, value);
            writer.WriteEndElement();

            writer.WriteEndElement();
        }
    }
}
</code></pre>

<p>Any other XML Serialization gotchas out there?</p>

[{'answer_id': 68005, 'author': 'Charles Graham', 'author_id': 7705, 'author_profile': 'https://Stackoverflow.com/users/7705', 'pm_score': 2, 'selected': False, 'text': '<p>Private variables/properties are not serialized in the default mechanism for XML serialization, but are in binary serialization.</p>\n'}, {'answer_id': 68014, 'author': 'Eric Z Beard', 'author_id': 1219, 'author_profile': 'https://Stackoverflow.com/users/1219', 'pm_score': 3, 'selected': False, 'text': '<p>Oh here\'s a good one: since the XML serialization code is generated and placed in a separate DLL, you don\'t get any meaningful error when there is a mistake in your code that breaks the serializer.  Just something like "unable to locate s3d3fsdf.dll".  Nice.</p>\n'}, {'answer_id': 68057, 'author': 'Dr8k', 'author_id': 6014, 'author_profile': 'https://Stackoverflow.com/users/6014', 'pm_score': 0, 'selected': False, 'text': "<blockquote>\n  <p>Private variables/properties are not\n  serialized in XML serialization, but\n  are in binary serialization.</p>\n</blockquote>\n\n<p>I believe this also gets you if you are exposing the private members through public properties - the private members don't get serialised so the public members are all referencing null values.</p>\n"}, {'answer_id': 68225, 'author': 'Charles Graham', 'author_id': 7705, 'author_profile': 'https://Stackoverflow.com/users/7705', 'pm_score': 5, 'selected': False, 'text': "<p>I can't make comments yet, so I will comment on Dr8k's post and make another observation.  Private variables that are exposed as public getter/setter properties, and do get serialized/deserialized as such through those properties.  We did it at my old job al the time.</p>\n\n<p>One thing to note though is that if you have any logic in those properties, the logic is run, so sometimes, the order of serialization actually matters.  The members are <em>implicitly</em> ordered by how they are ordered in the code, but there are no guarantees, especially when you are inheriting another object.  Explicitly ordering them is a pain in the rear.</p>\n\n<p>I've been burnt by this in the past.</p>\n"}, {'answer_id': 68476, 'author': 'Community', 'author_id': -1, 'author_profile': 'https://Stackoverflow.com/users/-1', 'pm_score': 3, 'selected': False, 'text': '<p><code>IEnumerables&lt;T&gt;</code> that are generated via yield returns are not serializable.  This is because the compiler generates a separate class to implement yield return and that class is not marked as serializable.</p>\n'}, {'answer_id': 69072, 'author': 'user7116', 'author_id': 7116, 'author_profile': 'https://Stackoverflow.com/users/7116', 'pm_score': 2, 'selected': False, 'text': '<p>If your XML Serialization generated assembly is not in the same Load context as the code attempting to use it, you will run into awesome errors like:</p>\n\n<pre><code>System.InvalidOperationException: There was an error generating the XML document.\n---System.InvalidCastException: Unable to cast object\nof type \'MyNamespace.Settings\' to type \'MyNamespace.Settings\'. at\nMicrosoft.Xml.Serialization.GeneratedAssembly.\n  XmlSerializationWriterSettings.Write3_Settings(Object o)\n</code></pre>\n\n<p>The cause of this for me was a plugin loaded using <a href="http://msdn.microsoft.com/en-us/library/1009fa28(VS.80).aspx#remarksToggle" rel="nofollow noreferrer" title="Assembly.LoadFrom Method">LoadFrom context</a> which has many disadvantages to using the Load context. Quite a bit of fun tracking that one down.</p>\n'}, {'answer_id': 97376, 'author': 'Kalid', 'author_id': 109, 'author_profile': 'https://Stackoverflow.com/users/109', 'pm_score': 5, 'selected': False, 'text': '<p>Another huge gotcha: when outputting XML through a web page (ASP.NET), you don\'t want to include the <a href="http://en.wikipedia.org/wiki/UTF-8#Byte_order_mark" rel="noreferrer">Unicode Byte-Order Mark</a>. Of course, the ways to use or not use the BOM are almost the same:</p>\n\n<h3>BAD (includes BOM):</h3>\n\n<pre><code>XmlTextWriter wr = new XmlTextWriter(stream, new System.Text.Encoding.UTF8);\n</code></pre>\n\n<h3>GOOD:</h3>\n\n<pre><code>XmlTextWriter  wr = new XmlTextWriter(stream, new System.Text.UTF8Encoding(false))\n</code></pre>\n\n<p>You can explicitly pass false to indicate you don\'t want the BOM. Notice the clear, obvious difference between <code>Encoding.UTF8</code> and <code>UTF8Encoding</code>.</p>\n\n<p>The three extra BOM Bytes at the beginning are (0xEFBBBF) or (239 187 191).</p>\n\n<p>Reference: <a href="http://chrislaco.com/blog/troubleshooting-common-problems-with-the-xmlserializer/" rel="noreferrer">http://chrislaco.com/blog/troubleshooting-common-problems-with-the-xmlserializer/</a></p>\n'}, {'answer_id': 138713, 'author': 'annakata', 'author_id': 13018, 'author_profile': 'https://Stackoverflow.com/users/13018', 'pm_score': 2, 'selected': False, 'text': '<p>I can\'t really explain this one, but I found this won\'t serialise:</p>\n\n<pre><code>[XmlElement("item")]\npublic myClass[] item\n{\n    get { return this.privateList.ToArray(); }\n}\n</code></pre>\n\n<p>but this will:</p>\n\n<pre><code>[XmlElement("item")]\npublic List&lt;myClass&gt; item\n{\n    get { return this.privateList; }\n}\n</code></pre>\n\n<p>And also worth noting that if you\'re serialising to a memstream, you might want to seek to 0 before you use it.</p>\n'}, {'answer_id': 138846, 'author': 'ilitirit', 'author_id': 9825, 'author_profile': 'https://Stackoverflow.com/users/9825', 'pm_score': 2, 'selected': False, 'text': '<p>If your XSD makes use of substitution groups, then chances are you can\'t (de)serialize it automatically.  You\'ll need to write your own serializers to handle this scenario.</p>\n\n<p>Eg.</p>\n\n<pre><code>&lt;xs:complexType name="MessageType" abstract="true"&gt;\n    &lt;xs:attributeGroup ref="commonMessageAttributes"/&gt;\n&lt;/xs:complexType&gt;\n\n&lt;xs:element name="Message" type="MessageType"/&gt;\n\n&lt;xs:element name="Envelope"&gt;\n    &lt;xs:complexType mixed="false"&gt;\n        &lt;xs:complexContent mixed="false"&gt;\n            &lt;xs:element ref="Message" minOccurs="0" maxOccurs="unbounded"/&gt;\n        &lt;/xs:complexContent&gt;\n    &lt;/xs:complexType&gt;\n&lt;/xs:element&gt;\n\n&lt;xs:element name="ExampleMessageA" substitutionGroup="Message"&gt;\n    &lt;xs:complexType mixed="false"&gt;\n        &lt;xs:complexContent mixed="false"&gt;\n                &lt;xs:attribute name="messageCode"/&gt;\n        &lt;/xs:complexContent&gt;\n    &lt;/xs:complexType&gt;\n&lt;/xs:element&gt;\n\n&lt;xs:element name="ExampleMessageB" substitutionGroup="Message"&gt;\n    &lt;xs:complexType mixed="false"&gt;\n        &lt;xs:complexContent mixed="false"&gt;\n                &lt;xs:attribute name="messageCode"/&gt;\n        &lt;/xs:complexContent&gt;\n    &lt;/xs:complexType&gt;\n&lt;/xs:element&gt;\n</code></pre>\n\n<p>In this example, an Envelope can contain Messages.  However, the .NET\'s default serializer doesn\'t distinguish between Message, ExampleMessageA and ExampleMessageB.  It will only serialize to and from the base Message class.</p>\n'}, {'answer_id': 138872, 'author': 'Keith', 'author_id': 905, 'author_profile': 'https://Stackoverflow.com/users/905', 'pm_score': 2, 'selected': False, 'text': '<p>Be careful serialising types without explicit serialisation, it can result in delays while .Net builds them. I discovered this recently <a href="https://stackoverflow.com/questions/12135/filenotfoundexception-for-mscorlibxmlserializersdll-which-doesnt-exist">while serialising RSAParameters</a>.</p>\n'}, {'answer_id': 248786, 'author': 'Tim Robinson', 'author_id': 32133, 'author_profile': 'https://Stackoverflow.com/users/32133', 'pm_score': 3, 'selected': False, 'text': "<p>You can't serialize read-only properties. You must have a getter and a setter, even if you never intend to use deserialization to turn XML into an object.</p>\n\n<p>For the same reason, you can't serialize properties that return interfaces: the deserializer wouldn't know what concrete class to instantiate.</p>\n"}, {'answer_id': 380572, 'author': 'Max Galkin', 'author_id': 2351099, 'author_profile': 'https://Stackoverflow.com/users/2351099', 'pm_score': 2, 'selected': False, 'text': '<p>You may face problems serializing objects of type Color and/or Font.</p>\n\n<p>Here are the advices, that helped me:</p>\n\n<p><a href="http://www.codeproject.com/KB/XML/xmlsettings.aspx" rel="nofollow noreferrer">http://www.codeproject.com/KB/XML/xmlsettings.aspx</a></p>\n\n<p><a href="http://www.codeproject.com/KB/cs/GenericXmlSerializition.aspx" rel="nofollow noreferrer">http://www.codeproject.com/KB/cs/GenericXmlSerializition.aspx</a></p>\n'}, {'answer_id': 391841, 'author': 'Max Galkin', 'author_id': 2351099, 'author_profile': 'https://Stackoverflow.com/users/2351099', 'pm_score': 3, 'selected': False, 'text': '<p>One more thing to note: you can\'t serialize private/protected class members if you are using the "default" XML serialization. </p>\n\n<p>But you can specify custom XML serialization logic implementing IXmlSerializable in your class and serialize any private fields you need/want.</p>\n\n<p><a href="http://msdn.microsoft.com/en-us/library/system.xml.serialization.ixmlserializable.aspx" rel="noreferrer">http://msdn.microsoft.com/en-us/library/system.xml.serialization.ixmlserializable.aspx</a></p>\n'}, {'answer_id': 414644, 'author': 'realgt', 'author_id': 46459, 'author_profile': 'https://Stackoverflow.com/users/46459', 'pm_score': 4, 'selected': False, 'text': '<p>When serializing into an XML string from a memory stream, be sure to use MemoryStream#ToArray() instead of MemoryStream#GetBuffer() or you will end up with junk characters that won\'t deserialize properly (because of the extra buffer allocated).</p>\n\n<p><a href="http://msdn.microsoft.com/en-us/library/system.io.memorystream.getbuffer(VS.80).aspx" rel="noreferrer">http://msdn.microsoft.com/en-us/library/system.io.memorystream.getbuffer(VS.80).aspx</a></p>\n'}, {'answer_id': 552603, 'author': 'Benjol', 'author_id': 11410, 'author_profile': 'https://Stackoverflow.com/users/11410', 'pm_score': 3, 'selected': False, 'text': "<p>Can't serialize an object which doesn't have a parameterless construtor (just got bitten by that one).</p>\n\n<p>And for some reason, from the following properties, Value gets serialised, but not FullName:</p>\n\n<pre><code>    public string FullName { get; set; }\n    public double Value { get; set; }\n</code></pre>\n\n<p>I never got round to working out why, I just changed Value to internal...</p>\n"}, {'answer_id': 1218763, 'author': 'Allon Guralnek', 'author_id': 149265, 'author_profile': 'https://Stackoverflow.com/users/149265', 'pm_score': 3, 'selected': False, 'text': "<p>If the serializer encounters a member/property that has an interface as its type, it won't serialize. For example, the following won't serialize to XML:</p>\n\n<pre><code>public class ValuePair\n{\n    public ICompareable Value1 { get; set; }\n    public ICompareable Value2 { get; set; }\n}\n</code></pre>\n\n<p>Though this will serialize:</p>\n\n<pre><code>public class ValuePair\n{\n    public object Value1 { get; set; }\n    public object Value2 { get; set; }\n}\n</code></pre>\n"}, {'answer_id': 6358946, 'author': 'John Saunders', 'author_id': 76337, 'author_profile': 'https://Stackoverflow.com/users/76337', 'pm_score': 2, 'selected': False, 'text': '<p>See "<a href="http://msdn.microsoft.com/en-us/library/bb885287.aspx" rel="nofollow">Advanced XML Schema Definition Language Attributes Binding Support</a>" for details of what is supported by the XML Serializer, and for details on the way in which the supported XSD features are supported.</p>\n'}, {'answer_id': 7236099, 'author': 'James Hulse', 'author_id': 400193, 'author_profile': 'https://Stackoverflow.com/users/400193', 'pm_score': 2, 'selected': False, 'text': "<p>Properties marked with the <code>Obsolete</code> attribute aren't serialized. I haven't tested with <code>Deprecated</code> attribute but I assume it would act the same way.</p>\n"}, {'answer_id': 9760461, 'author': 'MarkJ', 'author_id': 15639, 'author_profile': 'https://Stackoverflow.com/users/15639', 'pm_score': 2, 'selected': False, 'text': '<p>If you try to serialize an array, <code>List&lt;T&gt;</code>, or <code>IEnumerable&lt;T&gt;</code> which contains instances of <em>subclasses</em> of <code>T</code>, you need to use the <a href="http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlarrayitemattribute%28VS.71%29.aspx" rel="nofollow">XmlArrayItemAttribute</a> to list all the subtypes being used. Otherwise you will get an unhelpful <code>System.InvalidOperationException</code> at runtime when you serialize. </p>\n\n<p>Here is part of a full example from <a href="http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlarrayitemattribute%28VS.71%29.aspx" rel="nofollow">the documentation</a> </p>\n\n<pre><code>public class Group\n{  \n   /* The XmlArrayItemAttribute allows the XmlSerializer to insert both the base \n      type (Employee) and derived type (Manager) into serialized arrays. */\n\n   [XmlArrayItem(typeof(Manager)), XmlArrayItem(typeof(Employee))]\n   public Employee[] Employees;\n</code></pre>\n'}]
['https://Stackoverflow.com/questions/67959', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/109/']