Exception.SerializeObjectState Event
Definition
Important
Some information relates to prerelease product that may be substantially modified before it’s released. Microsoft makes no warranties, express or implied, with respect to the information provided here.
Caution
BinaryFormatter serialization is obsolete and should not be used. See https://aka.ms/binaryformatter for more information.
Occurs when an exception is serialized to create an exception state object that contains serialized data about the exception.
protected:
event EventHandler<System::Runtime::Serialization::SafeSerializationEventArgs ^> ^ SerializeObjectState;
protected event EventHandler<System.Runtime.Serialization.SafeSerializationEventArgs>? SerializeObjectState;
[System.Obsolete("BinaryFormatter serialization is obsolete and should not be used. See https://aka.ms/binaryformatter for more information.", DiagnosticId="SYSLIB0011", UrlFormat="https://aka.ms/dotnet-warnings/{0}")]
protected event EventHandler<System.Runtime.Serialization.SafeSerializationEventArgs>? SerializeObjectState;
protected event EventHandler<System.Runtime.Serialization.SafeSerializationEventArgs> SerializeObjectState;
member this.SerializeObjectState : EventHandler<System.Runtime.Serialization.SafeSerializationEventArgs>
[<System.Obsolete("BinaryFormatter serialization is obsolete and should not be used. See https://aka.ms/binaryformatter for more information.", DiagnosticId="SYSLIB0011", UrlFormat="https://aka.ms/dotnet-warnings/{0}")>]
member this.SerializeObjectState : EventHandler<System.Runtime.Serialization.SafeSerializationEventArgs>
Protected Custom Event SerializeObjectState As EventHandler(Of SafeSerializationEventArgs)
Event Type
- Attributes
Examples
The following example defines a BadDivisionException
that handles the SerializeObjectState event. It also contains a state object, which is a nested structure named BadDivisionExceptionState
that implements the ISafeSerializationData interface.
using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
public class Example
{
public static void Main()
{
bool serialized = false;
var formatter = new BinaryFormatter();
Double[] values = { 3, 2, 1 };
Double divisor = 0;
foreach (var value in values) {
try {
BadDivisionException ex = null;
if (divisor == 0) {
if (! serialized) {
// Instantiate the exception object.
ex = new BadDivisionException(0);
// Serialize the exception object.
var fs = new FileStream("BadDivision1.dat",
FileMode.Create);
formatter.Serialize(fs, ex);
fs.Close();
Console.WriteLine("Serialized the exception...");
}
else {
// Deserialize the exception.
var fs = new FileStream("BadDivision1.dat",
FileMode.Open);
ex = (BadDivisionException) formatter.Deserialize(fs);
// Reserialize the exception.
fs.Position = 0;
formatter.Serialize(fs, ex);
fs.Close();
Console.WriteLine("Reserialized the exception...");
}
throw ex;
}
Console.WriteLine("{0} / {1} = {1}", value, divisor, value/divisor);
}
catch (BadDivisionException e) {
Console.WriteLine("Bad divisor from a {0} exception: {1}",
serialized ? "deserialized" : "new", e.Divisor);
serialized = true;
}
}
}
}
[Serializable] public class BadDivisionException : Exception
{
// Maintain an internal BadDivisionException state object.
[NonSerialized] private BadDivisionExceptionState state = new BadDivisionExceptionState();
public BadDivisionException(Double divisor)
{
state.Divisor = divisor;
HandleSerialization();
}
private void HandleSerialization()
{
SerializeObjectState += delegate(object exception, SafeSerializationEventArgs eventArgs)
{
eventArgs.AddSerializedState(state);
};
}
public Double Divisor
{ get { return state.Divisor; } }
[Serializable] private struct BadDivisionExceptionState : ISafeSerializationData
{
private Double badDivisor;
public Double Divisor
{ get { return badDivisor; }
set { badDivisor = value; } }
void ISafeSerializationData.CompleteDeserialization(object deserialized)
{
var ex = deserialized as BadDivisionException;
ex.HandleSerialization();
ex.state = this;
}
}
}
// The example displays the following output:
// Serialized the exception...
// Bad divisor from a new exception: 0
// Reserialized the exception...
// Bad divisor from a deserialized exception: 0
// Reserialized the exception...
// Bad divisor from a deserialized exception: 0
Imports System.IO
Imports System.Runtime.Serialization
Imports System.Runtime.Serialization.Formatters.Binary
Module Example
Public Sub Main()
Dim serialized As Boolean = False
Dim formatter As New BinaryFormatter()
Dim values() As Double = { 3, 2, 1 }
Dim divisor As Double = 0
For Each value In values
Try
Dim ex As BadDivisionException = Nothing
If divisor = 0 Then
If Not serialized Then
' Instantiate the exception object.
ex = New BadDivisionException(0)
' Serialize the exception object.
Dim fs As New FileStream("BadDivision1.dat",
FileMode.Create)
formatter.Serialize(fs, ex)
fs.Close()
Console.WriteLine("Serialized the exception...")
Else
' Deserialize the exception.
Dim fs As New FileStream("BadDivision1.dat",
FileMode.Open)
ex = CType(formatter.Deserialize(fs), BadDivisionException)
' Reserialize the exception.
fs.Position = 0
formatter.Serialize(fs, ex)
fs.Close()
Console.WriteLine("Reserialized the exception...")
End If
Throw ex
End If
Console.WriteLine("{0} / {1} = {1}", value, divisor, value/divisor)
Catch e As BadDivisionException
Console.WriteLine("Bad divisor from a {0} exception: {1}",
If(serialized, "deserialized", "new"), e.Divisor)
serialized = True
End Try
Next
End Sub
End Module
<Serializable> Public Class BadDivisionException : Inherits Exception
' Maintain an internal BadDivisionException state object.
<NonSerialized> Private state As New BadDivisionExceptionState()
Public Sub New(divisor As Double)
state.Divisor = divisor
HandleSerialization()
End Sub
Private Sub HandleSerialization()
AddHandler SerializeObjectState,
Sub(exception As Object, eventArgs As SafeSerializationEventArgs)
eventArgs.AddSerializedState(state)
End Sub
End Sub
Public ReadOnly Property Divisor As Double
Get
Return state.Divisor
End Get
End Property
<Serializable> Private Structure BadDivisionExceptionState
Implements ISafeSerializationData
private badDivisor As Double
Public Property Divisor As Double
Get
Return badDivisor
End Get
Set
badDivisor = value
End Set
End Property
Sub CompleteDeserialization(deserialized As Object) _
Implements ISafeSerializationData.CompleteDeserialization
Dim ex As BadDivisionException = TryCast(deserialized, BadDivisionException)
ex.HandleSerialization()
ex.state = Me
End Sub
End Structure
End Class
' The example displays the following output:
' Serialized the exception...
' Bad divisor from a new exception: 0
' Reserialized the exception...
' Bad divisor from a deserialized exception: 0
' Reserialized the exception...
' Bad divisor from a deserialized exception: 0
The BadDivisionException
exception is thrown when a floating-point division by zero occurs. During the first division by zero, the example instantiates a BadDivisionException
object, serializes it, and throws the exception. When subsequent divisions by zero occur, the example deserializes the previously serialized object, reserializes it, and throws the exception. To provide for object serialization, deserialization, reserialization, and deserialization, the example adds the SerializeObjectState event handler both in the BadDivisionException
class constructor and in the ISafeSerializationData.CompleteDeserialization implementation.
Remarks
The exception state object implements the ISafeSerializationData interface.
When the SerializeObjectState event is subscribed to, the exception is deserialized and created as an empty exception. The exception's constructor is not run, and the exception state is also deserialized. The CompleteDeserialization callback method of the exception state object is then notified so that it can push deserialized data into the empty exception.
The SerializeObjectState event enables transparent exception types to serialize and deserialize exception data. Transparent code can execute commands within the bounds of the permission set it is operating within, but cannot execute, call, derive from, or contain critical code.
If the SerializeObjectState event is not subscribed to, deserialization occurs as usual using the Exception constructor.
Typically, a handler for the SerializeObjectState event is added in the exception's constructor to provide for its serialization. But because the constructor is not executed when the SerializeObjectState event handler executes, serializing a deserialized exception can throw a SerializationException exception when you try to deserialize the exception. To avoid this, you should also add the handler for the SerializeObjectState event in the ISafeSerializationData.CompleteDeserialization method. See the Examples section for an illustration.
Notes to Inheritors
If this event is subscribed to and used, all derived types that follow in the inheritance hierarchy must implement the same serialization mechanism.