title: XML Serialization: Problem deserializing an abstract property
body: <p>I am still trying to wrap my brain around this whole xml serialization thing, and it appears I am in need of some assistance yet again.</p>
  
  <p>I need to be able to deserialize a property of an abstract type. This type will have many different concrete types being added over time, and is referenced in a lot of different models, so explicitly listing each of the concrete types is not an ideal solution.</p>
  
  <p>I have read the <a href="https://stackoverflow.com/questions/20084/xml-serialization-and-inherited-types">XML Serialization and Inherited Types</a> thread, and have come up with the following:</p>
  
  <pre><code>&lt;Page&gt;
    &lt;introCommand&gt;
      &lt;PlayElement /&gt;
    &lt;/introCommand&gt;
  &lt;/Page&gt;
  </code></pre>
  
  <p>**</p>
  
  <pre><code>namespace TestService
  {
      public class Page
      {
          [XmlElement("introCommand", Type = typeof(XmlCommandSerializer&lt;AbstractCommandModel&gt;))]
          //[XmlElement(typeof(PlayElement))] **NOTE: the example works if I use this instead
          public AbstractCommandModel introCommand;
      }
  }
  </code></pre>
  
  <p>**</p>
  
  <pre><code>namespace TestService
  {
      public class AbstractCommandModel
      {
      }
  }
  </code></pre>
  
  <p>**</p>
  
  <pre><code>namespace TestService
  {
      public class PlayElement : AbstractCommandModel
      {
  
      }
  }
  </code></pre>
  
  <p>**</p>
  
  <pre><code>namespace TestService
  {
      public class XmlCommandSerializer&lt;AbstractCommandModel&gt; : IXmlSerializable
      {
          // Override the Implicit Conversions Since the XmlSerializer
          // Casts to/from the required types implicitly.
          public static implicit operator AbstractCommandModel(XmlCommandSerializer&lt;AbstractCommandModel&gt; o)
          {
              return o.Data;
          }
  
          public static implicit operator XmlCommandSerializer&lt;AbstractCommandModel&gt;(AbstractCommandModel o)
          {
              return o == null ? null : new XmlCommandSerializer&lt;AbstractCommandModel&gt;(o);
          }
  
          private AbstractCommandModel _data;
          /// &lt;summary&gt;
          /// [Concrete] Data to be stored/is stored as XML.
          /// &lt;/summary&gt;
          public AbstractCommandModel Data
          {
              get { return _data; }
              set { _data = value; }
          }
  
          /// &lt;summary&gt;
          /// **DO NOT USE** This is only added to enable XML Serialization.
          /// &lt;/summary&gt;
          /// &lt;remarks&gt;DO NOT USE THIS CONSTRUCTOR&lt;/remarks&gt;
          public XmlCommandSerializer()
          {
              // Default Ctor (Required for Xml Serialization - DO NOT USE)
          }
  
          /// &lt;summary&gt;
          /// Initialises the Serializer to work with the given data.
          /// &lt;/summary&gt;
          /// &lt;param name="data"&gt;Concrete Object of the AbstractCommandModel Specified.&lt;/param&gt;
          public XmlCommandSerializer(AbstractCommandModel data)
          {
              _data = data;
          }
  
          #region IXmlSerializable Members
  
          public System.Xml.Schema.XmlSchema GetSchema()
          {
              return null; // this is fine as schema is unknown.
          }
  
          public void ReadXml(System.Xml.XmlReader reader)
          {
              // Cast the Data back from the Abstract Type.
              string typeAttrib = reader.GetAttribute("type");
  
              // Ensure the Type was Specified
              if (typeAttrib == null)
                  throw new ArgumentNullException("Unable to Read Xml Data for Abstract Type '" + typeof(AbstractCommandModel).Name +
                      "' because no 'type' attribute was specified in the XML.");
  
              Type type = Type.GetType(typeAttrib);
  
              // Check the Type is Found.
              if (type == null)
                  throw new InvalidCastException("Unable to Read Xml Data for Abstract Type '" + typeof(AbstractCommandModel).Name +
                      "' because the type specified in the XML was not found.");
  
              // Check the Type is a Subclass of the AbstractCommandModel.
              if (!type.IsSubclassOf(typeof(AbstractCommandModel)))
                  throw new InvalidCastException("Unable to Read Xml Data for Abstract Type '" + typeof(AbstractCommandModel).Name +
                      "' because the Type specified in the XML differs ('" + type.Name + "').");
  
              // Read the Data, Deserializing based on the (now known) concrete type.
              reader.ReadStartElement();
              this.Data = (AbstractCommandModel)new
                  XmlSerializer(type).Deserialize(reader);
              reader.ReadEndElement();
          }
  
          public void WriteXml(System.Xml.XmlWriter writer)
          {
              // Write the Type Name to the XML Element as an Attrib and Serialize
              Type type = _data.GetType();
  
              // BugFix: Assembly must be FQN since Types can/are external to current.
              writer.WriteAttributeString("type", type.AssemblyQualifiedName);
              new XmlSerializer(type).Serialize(writer, _data);
          }
  
          #endregion
      }
  }
  </code></pre>
  
  <p>However, when I run the deserializer I get an <em>InvalidOperationException</em> stating <em>"There is an error in XML document (3,3)."</em>. The only thing I have changed from the example in the before mentioned thread is the class names.</p>
  
  <p>Am I on the right track with this? If so, what did I mess up to cause this error?</p>