title: DataContractSerialization of generic type hierarchies
body: <p>The following program, which tries to serialize and then deserialize an object of a generic type from a hierarchy, fails with the error listed below the code.</p>
  
  <p>How do I make it work?</p>
  
  <h3>Code:</h3>
  
  <pre><code>[DataContract]
  [KnownType(nameof(GetKnownTypes))]
  public abstract class Base&lt;T&gt;
  {
      private static Type[] GetKnownTypes()
      {
          return new[] {typeof(DerivedA&lt;T&gt;)};
      }
  }
  
  
  [DataContract]
  public class DerivedA&lt;T&gt; : Base&lt;T&gt;
  {
      [DataMember]
      public T Foo { get; set; }
  }
  
  class Program
  {
      private static void Main()
      {
          // This works fine
          var foo = new DerivedA&lt;string&gt; { Foo = "foo" };
          var xml = Serialize(foo);
          var foo2 = Deserialize&lt;DerivedA&lt;string&gt;&gt;(xml);
          Console.WriteLine(foo2.Foo); // foo
  
          // This throws the exception below
          // (from serializer.ReadObject() in the Deserialize method)
          var foo3 = Deserialize&lt;Base&lt;string&gt;&gt;(xml);
      }
  
      private static string Serialize&lt;T&gt;(T o)
      {
          string result = null;
          var serializer = new DataContractSerializer(o.GetType());
          using (var stream = new MemoryStream())
          {
              serializer.WriteObject(stream, o);
              stream.Position = 0;
  
              var reader = new StreamReader(stream);
              result = reader.ReadToEnd();
          }
          return result;
      }
  
      private static T Deserialize&lt;T&gt;(string xml)
      {
          var result = default(T);
          var serializer = new DataContractSerializer(typeof(T));
          using (var stream = new MemoryStream())
          {
              var writer = new StreamWriter(stream);
              writer.Write(xml);
              writer.Flush();
              stream.Position = 0;
  
              result = (T)serializer.ReadObject(stream);
          }
          return result;
      }
  }
  </code></pre>
  
  <h3>The exception:</h3>
  
  <pre><code>Unhandled Exception: System.Runtime.Serialization.SerializationException: Error in line 1 position 139. Expecting element 'BaseOfstring' from namespace 'http://schemas.datacontract.org/2004/07/ConsoleApplication7'.. Encountered 'Element'  with name 'DerivedAOfstring', namespace 'http://schemas.datacontract.org/2004/07/ConsoleApplication7'.
    at System.Runtime.Serialization.DataContractSerializer.InternalReadObject(XmlReaderDelegator xmlReader, Boolean verifyObjectName, DataContractResolver dataContractResolver)
    at System.Runtime.Serialization.XmlObjectSerializer.ReadObjectHandleExceptions(XmlReaderDelegator reader, Boolean verifyObjectName, DataContractResolver dataContractResolver)
    at System.Runtime.Serialization.XmlObjectSerializer.ReadObject(XmlDictionaryReader reader)
    at System.Runtime.Serialization.XmlObjectSerializer.ReadObject(Stream stream)
    at ConsoleApplication7.Program.Deserialize[T](String xml) in c:\users\tly01\documents\visual studio 2015\Projects\ConsoleApplication7\ConsoleApplication7\Program.cs:line 65
  </code></pre>
  
  <p>The most interesting part of the message makes it pretty clear what went wrong:</p>
  
  <blockquote>
    <p>Expecting element 'BaseOfstring' from namespace . Encountered 'Element'  with name 'DerivedAOfstring', namespace .</p>
  </blockquote>
  
  <p>Sure enough, <code>xml</code> in the main method above is this (with whitespace added):</p>
  
  <pre><code>&lt;DerivedAOfstring
      xmlns="http://schemas.datacontract.org/2004/07/ConsoleApplication7"
      xmlns:i="http://www.w3.org/2001/XMLSchema-instance"&gt;
    &lt;Foo&gt;foo&lt;/Foo&gt;
  &lt;/DerivedAOfstring&gt;
  </code></pre>
  
  <p>I realize that I somehow have to make the serializer aware of my type hierarchy, but I've tried a lot of different variants of the <code>KnownType</code> attribute in the listing above, and none of them have been fruitful. What's the correct way to make this work?</p>