title: Serialization in C# with a derived class
body: <p>I'm building a notification framework and for that I'm serializing and deserializing a basic class, from which all the classes I want to send will derive.</p>
  
  <p>The problem is that the code compiles, but when I actually try to serialize this basic class I get an error saying </p>
  
  <blockquote>
    <p>System.Runtime.Serialization.SerializationException: Type 'Xxx.DataContracts.WQAllocationUpdate' in Assembly 'Xxx.DataContract, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' is not marked as serializable.</p>
  </blockquote>
  
  <p>Here is the code :</p>
  
  <pre><code>public class WCallUpdate : NotificationData
  {
      private string m_from = "";
      [DataMember]
      public string From
      {
          get { return m_from; }
          set { m_from = value; }
      }
      private WCall m_wCall = new WCall();
      [DataMember]
      public WCall Call
      {
          get { return m_wCall; }
          set { m_wCall = value; }
      }
  }
  </code></pre>
  
  <p>The <code>DataContract</code> for the Notification is:</p>
  
  <pre><code>/// &lt;summary&gt;
  /// Basic class used in the notification service
  /// &lt;/summary&gt;
  [DataContract]
  public class NotificationData
  {
  }
  
  /// &lt;summary&gt;
  /// Enum containing all the events used in the application
  /// &lt;/summary&gt;
  [DataContract]
  public enum NotificationTypeKey
  {
      [EnumMember]
      Default = 0,
      [EnumMember]
      IWorkQueueServiceAttributionAddedEvent = 1,
      [EnumMember]
      IWorkQueueServiceAttributionUpdatedEvent = 2,
      [EnumMember]
      IWorkQueueServiceAttributionRemovedEvent = 3,
  }
  </code></pre>
  
  <p>The code used to serialize the data is:</p>
  
  <pre><code>    #region Create Message
      /// &lt;summary&gt;
      /// Creates a memoryStream from a notificationData
      /// note: we insert also the notificationTypeKey at the beginning of the
      /// stream in order to treat the memoryStream correctly on the client side
      /// &lt;/summary&gt;
      /// &lt;param name="notificationTypeKey"&gt;&lt;/param&gt;
      /// &lt;param name="notificationData"&gt;&lt;/param&gt;
      /// &lt;returns&gt;&lt;/returns&gt;
      public MemoryStream CreateMessage(NotificationTypeKey notificationTypeKey, NotificationData notificationData)
      {
          MemoryStream stream = new MemoryStream();
          BinaryFormatter formatter = new BinaryFormatter();
          try
          {
              formatter.Serialize(stream, notificationTypeKey);
              formatter.Serialize(stream, notificationData);
          }
          catch (Exception ex)
          {
              Logger.Exception(ex);
          }
          return stream;
      }
      #endregion
  </code></pre>
  
  <p>When I try to create a message:</p>
  
  <pre><code>WCallUpdate  m_wCallUpdate = new WCallUpdate();
  NotificationTypeKey  m_notificationTypeKey = new NotificationTypeKey.Default;
  CreateMessage(notificationTypeKey , wCallUpdate );
  </code></pre>
  
  <p>I got the following error:</p>
  
  <pre><code>System.Runtime.Serialization.SerializationException: Type 'Xxx.DataContracts.WCall' in Assembly 'Xxx.DataContract, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' is not marked as serializable.
     at System.Runtime.Serialization.FormatterServices.InternalGetSerializableMembers(RuntimeType type)
     at System.Runtime.Serialization.FormatterServices.GetSerializableMembers(Type type, StreamingContext context)
     at System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitMemberInfo()
     at System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitSerialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter)
     at System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.Serialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter)
     at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Write(WriteObjectInfo objectInfo, NameInfo memberNameInfo, NameInfo typeNameInfo)
     at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Serialize(Object graph, Header[] inHeaders, __BinaryWriter serWriter, Boolean fCheck)
     at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, Object graph, Header[] headers, Boolean fCheck)
     at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, Object graph)
     at Xxx.Notification.NotificationMessageFactory.CreateMessage(NotificationTypeKey notificationTypeKey, NotificationData notificationData) in Xxx.Notification\NotificationCenter.cs:line 36
  </code></pre>
  
  <p>If I put the Serializable flag before the <code>DataContract</code> one does not solve the problem.</p>
  
  <hr>
  
  <p>thank you for the fast answer.
  Sorry that i forgot to put the code of the NotificationData (edited in the main post)</p>
  
  <p>I tried putting the Serializable attribute to both class without success :(</p>
  
  <pre><code>#region NotificationData
  /// &lt;summary&gt;
  /// Basic class used in the notification service
  /// &lt;/summary&gt;
  [Serializable]
  [DataContract]
  public class NotificationData
  {
  }
  #endregion
  </code></pre>
  
  <p>and </p>
  
  <pre><code>[Serializable]
  public class WCallUpdate : NotificationData
  {
      private string m_from = "";
      [DataMember]
      public string From
      {
          get { return m_from; }
          set { m_from = value; }
      }
      private WCall m_wCall = new WCall();
      [DataMember]
      public WCall Call
      {
          get { return m_wCall; }
          set { m_wCall = value; }
      }
  }
  </code></pre>
  
  <p>**Edit: ** Mea culpa afterall :) You were both right.
  I forgot to spread the <code>[Serializable]</code> Attribute to all the child class.
  After updating and compiling, i got no longer the exception.
  thank you both for your correct answers :)</p>
  
  <hr>
  
  <p>@Marc Gravel:
  Actually i thought about what you are suggesting, and created the following DataContractSerializer, but I'm not sure this will work? As my classes use other classes? the big problem with the DataContractSerializer is that you need to specify the type of the object you want to serialize, and as my class uses other class as private fields, that might cause a problem right?</p>
  
  <pre><code>#region DataContractSerializer
          /// &lt;summary&gt;
          /// Creates a Data Contract Serializer for the provided type. The type must be marked with
          /// the data contract attribute to be serialized successfully.
          /// &lt;/summary&gt;
          /// &lt;typeparam name="T"&gt;The type to be serialized&lt;/typeparam&gt;
          /// &lt;returns&gt;A data contract serializer&lt;/returns&gt;
          public static DataContractSerializer CreateDataContractSerializer&lt;T&gt;() where T : class
          {
              DataContractSerializer serializer = new DataContractSerializer(typeof(T));
              return serializer;
          }
          #endregion
  </code></pre>