Version-Tolerant Serialization Callbacks

The data contract programming model fully supports the version-tolerant serialization callback methods that the BinaryFormatter and SoapFormatter classes support.

Version-Tolerant Attributes

There are four callback attributes. Each attribute can be applied to a method that the serialization/deserialization engine calls at various times. The table below explains when to use each attribute.

Attribute When the corresponding method is called
OnSerializingAttribute Called before serializing the type.
OnSerializedAttribute Called after serializing the type.
OnDeserializingAttribute Called before deserializing the type.
OnDeserializedAttribute Called after deserializing the type.

The methods must accept a StreamingContext parameter.

These methods are primarily intended for use with versioning or initialization. During deserialization, no constructors are called. Therefore, data members may not be correctly initialized (to intended default values) if the data for these members is missing in the incoming stream, for example, if the data comes from a previous version of a type that is missing some data members. To correct this, use the callback method marked with the OnDeserializingAttribute, as shown in the following example.

You can mark only one method per type with each of the preceding callback attributes.

Example

// The following Data Contract is version 2 of an earlier data
// contract.
[DataContract]
public class Address
{
    [DataMember]
    public string Street;

    [DataMember]
    public string State;

    // This data member was added in version 2, and thus may be missing
    // in the incoming data if the data conforms to version 1 of the
    // Data Contract. Use the callback to add a default for this case.
    [DataMember(Order=2)]
    public string CountryRegion;

    // This method is used as a kind of constructor to initialize
    // a default value for the CountryRegion data member before
    // deserialization.
    [OnDeserializing]
    private void setDefaultCountryRegion(StreamingContext c)
    {
        CountryRegion = "Japan";
    }
}
' The following Data Contract is version 2 of an earlier data 
' contract.
<DataContract()> _
Public Class Address
    <DataMember()> _
    Public Street As String
    <DataMember()> _
    Public State As String

    ' This data member was added in version 2, and thus may be missing 
    ' in the incoming data if the data conforms to version 1 of the 
    ' Data Contract.
    <DataMember(Order:=2)> _
    Public CountryRegion As String

    ' This method is used as a kind of constructor to initialize
    ' a default value for the CountryRegion data member before 
    ' deserialization.
    <OnDeserializing()> _
    Private Sub setDefaultCountryRegion(ByVal c As StreamingContext)
        CountryRegion = "Japan"
    End Sub
End Class

See also