Поделиться через


Обратные вызовы сериализации, независимые от версий

Модель программирования контракта данных полностью поддерживает методы обратных вызовов независимой от версий сериализации, которые в свою очередь поддерживают классы BinaryFormatter и SoapFormatter.

Атрибуты независимой от версий сериализации

Существует четыре атрибута обратных вызовов. Каждый атрибут можно применить к методу, который вызывает ядро сериализации/десериализации в те или иные моменты времени. В таблице ниже представлены правила использования каждого атрибута.

Атрибут Когда вызывается соответствующий метод
OnSerializingAttribute Вызывается перед сериализацией типа.
OnSerializedAttribute Вызывается после сериализации типа.
OnDeserializingAttribute Вызывается перед десериализацией типа.
OnDeserializedAttribute Вызывается после десериализации типа.

Методы должны принимать параметр StreamingContext.

Эти методы в первую очередь предназначены для использования с управлением версиями или инициализацией. Во время десериализации конструкторы не вызываются. Поэтому возможна некорректная инициализация элементов данных (согласно заданным значениям по умолчанию), если данные для этих элементов отсутствуют во входящем потоке, например, если данные поступают из предыдущей версии типа, в котором отсутствуют некоторые элементы данных. Чтобы исправить такую ситуацию, используйте метод обратных вызовов, отмеченный OnDeserializingAttribute, как показано в следующем примере.

Для каждого типа можно отметить только один метод каждым из предыдущих атрибутов обратных вызовов.

Пример

// 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

См. также