31

Can all .NET exception objects be serialized?

yoozer8
  • 6,966
  • 6
  • 47
  • 84
Esteban Araya
  • 27,658
  • 22
  • 99
  • 139

5 Answers5

39

Yes and no. As Jeff and others have pointed out, the all exception classes should and almost always are serializable. If you run across a particular exception class that is not serializable, it is quite possibly a bug.

But when considering serializability you need to consider both the immediate class and all types which are members of this type (this is a recursive process). The base Exception class has a Data property which is of type IDictionary. This is problematic because it allows you, or anyone else, to add any object into the Exception. If this object is not serializable then serialization of the Exception will fail.

The default implementation of the Data property does do some basic checking to ensure an object being added is serializable. But it is flawed in several ways

  • Only does top level checking for serializability of a type and this check is only done by checking Type.IsSerializable (not a 100% solid check). 
  • The property is virtual. A derived exception type could override and use a Hashtable which does 0 checking.
hypehuman
  • 1,184
  • 1
  • 16
  • 35
JaredPar
  • 673,544
  • 139
  • 1,186
  • 1,421
16

Yes, but historically there have been (no pun intended) exceptions.

In other words, all Exceptions SHOULD be serializable, but some custom Exceptions from third party code may not be, depending on how they're implemented.

For example, in the .NET 1.0 era, exceptions from the official Microsoft Oracle database provider were not serializable, due to bugs in their code.

Jeff Atwood
  • 60,897
  • 45
  • 146
  • 152
  • 1
    Even as of .Net 4.5, some OleDB database exceptions and some System.Net exceptions are not de-serializable, due to lack of the required constructor. – drwatsoncode Dec 05 '12 at 20:13
12

This question has already been answered sufficiently, but for programmers who are new to C# or to Serialization, I think it is actually very helpful to point out that in general, Exceptions are NOT serializable!

That might sound a bit provocative, but let me explain.

It's true that all Exceptions implement the ISerializable interface, but this is only suggests that it should be serializable. But implementing the interface does NOT make an object Serializable (which in this context implies that the Exception can be both serialized and deserialized).

The most accurate answer to this question, as others have pointed out, is that many but certainly not all exceptions in the .Net Framework are Serializable. But if the question is using the term ".Net Exception" in a broader scope, e.g. an Exception derived from System.Exception, then the better and more helpful answer, in terms of best practices and avoiding bugs, is the assertion I made above, that in general Exceptions are not Serializable.

Here's why: As stated previously, for an Exception to be truly Serializable, it must have the proper constructor ctor(SerializationInfo, StreamingContext) and it must be decorated with the proper attribute. Importantly, neither of these constraints cause compiler errors if they are omitted!

What this means is that NO class derived from Exception is Serializable unless these extra, optional (from the compiler's perspective) steps are taken.

I.e. any unseasoned/unaware coder who derives a new Exception like below has just created an exception that is NOT Serializable.

class MyNewException : Exception { }

Visual studio has a great "Exception" snippet that lets you generate new serializable exceptions pretty quickly. But even in this case, there is nothing to remind or help the programmer to actually Serialize object properties. For example, even if the class below had the appropriate constructor and attribute, the MyNewField property would not be serialized without additional code in both the constructor and in GetObjectData.

class MyNewException : Exception 
{
    public MyNewField { get; set; }
}

So, the major point here is that if you must rely on proper Exception serialization & deserialization for some reason, should be completely aware that when it comes to any custom code or assemblies, there is no guarantee that it will work. Also, since the required constructor is usually protected, you will not necessarily be able to easily verify that it is present (without reflection).

In my own projects I have at some points created exception "Proxies" that can store some of the information (e.g. Message etc) from Exceptions that are not serializable themselves. These can be used to serialize some of the information, or alternatively to deserialize data written by an Exception that doesn't have the appropriate constructor.

drwatsoncode
  • 3,254
  • 26
  • 40
8

System.Exception implements ISerializable, but descendants might not deserialize if they don't implement the correct overloaded constructor with signature (SerializationInfo,StreamingContext).

Barry Kelly
  • 39,856
  • 4
  • 99
  • 180
  • 2
    In addition, if a derived exception does not properly call base.GetObjectData, then the base exception's information will not be serialized, which would result in errors upon de-serialization. In either case (missing constructor or failure to serialize base), the serialization will succeed, but de-serialization will throw an exception. – drwatsoncode Dec 05 '12 at 20:15
2

System.Exception implements ISerializable and it is the base class for all exceptions, so yes.

See: http://msdn.microsoft.com/en-us/library/system.exception.aspx

Jay Bazuzi
  • 41,333
  • 12
  • 104
  • 161
Matt Briggs
  • 38,679
  • 14
  • 86
  • 125
  • 6
    Except that derived classes do not inherit the SerializableAttribute, so each derived class must also be decorated in order for that class to be serialzable. – GalacticCowboy Dec 05 '08 at 01:46