CS.MEMB.NOT_SERIALIZABLE

Ensure entire graph of object can be serialized.

This rule points out all member fields which are not serializable in a serializable class. Fields marked with NonSerializedAttribute are excluded. Sometimes the rule can point out that you have to mark a type that is not under your control as "Serializable". For example, you may be using a system type that is not marked as serializable. In this case the fix will have to be to mark this member "NonSerializable" and you need to take care of initializing the member properly before it gets used in the deserialization context.

Vulnerability and risk

If an object of a class which does not conform to the above rule is serialized than an exception may occur.

Mitigation and prevention

If a class is serializable in a not customized manner (it is marked with SerializableAttribute and it does not implement ISerializable attribute) than all its fields must be either serializable or marked with NonSerializableAttribute.

Note: If a class is marked with SerializableAttribute and implements ISerializable then serialization is customized and this rule does not apply and .TEST will not show any violations for this rule.

Vulnerable code example

Copy
  public class Foo
  {
  }
  public class Bar
  {
  }
   [Serializable]
  public class MyClass
  {
     private Foo _foo;    // violation, class Foo is not
                         // serializable and field _foo is not
                         // skipped
                         // by NonSerializableAttribute
     private Bar _bar;     // violation, class Bar is not
                         // serializable and field _bar is not
                         // skipped
                         // by NonSerializableAttribute
     private static void Serialize(MyClass obj)
     {
         Stream stream = File.Open("foo.dat", FileMode.Create);
         BinaryFormatter formatter = new BinaryFormatter();
         formatter.Serialize(stream, obj); // an exception occurs
     }
 }

Fixed code example 1

Copy
  // There are two ways of fixing the above violations
  // Fix #1
  namespace Repair1
  {
      [Serializable]
      public class Foo
      {
      }
      public class Bar
     {
     }
     [Serializable]
     public class MyClass
     {
         private Foo _foo;    // fix, Foo is serializable
         [NonSerialized]
         private Bar _bar;    // fix, _bar is not serialized
         private static void MySerializeMethod(MyClass obj)
         {
             Stream stream = File.Open("foo.dat", FileMode.Create);
             BinaryFormatter formatter = new BinaryFormatter();
             formatter.Serialize(stream, obj);    // no exception,
                                                 // all members are
                                                 // serializable
         }
     }
 }

Fixed code example 2

Copy
  // Fix #2
  namespace Repair2
  {
      public class Foo
      {
      }
      public class Bar
      {
      }
      [Serializable]
     public class MyClass : ISerializable
     {
         private Foo _foo;
         private Bar _bar;
 
        private static void MySerializeMethod(MyClass obj)
         {
             Stream stream = File.Open("foo.dat", FileMode.Create);
             BinaryFormatter formatter = new BinaryFormatter();
             formatter.Serialize(stream, obj);     // no exception, all
                                                 // members are serializable
         }
         public void GetObjectData(
             SerializationInfo info,
             StreamingContext context)
         {
             /*
             ...
             */
         }
     }