ExtensionDataObject is not Marked as Serializable

If you use Data Contracts, then probably your classes implement the IExtensibleDataObject interface to allow (de)serialization of different versions of the data contract. I won’t go into details about the use of ExtensionDataObject, the type of the ExtensionData property you need to implement. I just want to point out a possible scenario, using sample code similar to that of MSDN:

    1: using System;
    2: using System.Runtime.Serialization;
    3: using System.Runtime.Serialization.Formatters.Binary;
    4:  
    5: namespace Test
    6: {
    7:     [Serializable]
    8:     [DataContract]
    9:     public class Person : IExtensibleDataObject
   10:     {
   11:         private ExtensionDataObject extensionData;
   12:  
   13:         public ExtensionDataObject ExtensionData
   14:         {
   15:             get
   16:             {
   17:                 return extensionData;
   18:             }
   19:             set
   20:             {
   21:                 extensionData = value;
   22:             }
   23:         }
   24:  
   25:         [DataMember]
   26:         public string Name;
   27:     }
   28:  
   29:     class Program
   30:     {
   31:         static void Main(string[] args)
   32:         {
   33:             try
   34:             {
   35:                 new BinaryFormatter().Serialize(Console.OpenStandardOutput(), new Person());
   36:             }
   37:             catch (Exception ex)
   38:             {
   39:                 Console.WriteLine(ex);
   40:             }
   41:         }
   42:     }
   43: }

If you serialize an object of the type used in this example, Person, using a BinaryFormatter, you will get the following exception:

System.Runtime.Serialization.SerializationException: Type 'System.Runtime.Serialization.ExtensionDataObject' in Assembly 'System.Runtime.Serialization, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' is not marked as serializable.

The solution is to mark the private extensionData field as non-serialized:

    1: [NonSerialized]
    2: private ExtensionDataObject extensionData;