Versionstolerante SerialisierungVersion tolerant serialization

In Version 1.0 und Version 1.1 von .NET Framework war das Erstellen serialisierbarer Typen problematisch, die für mehrere Anwendungsversionen verwendbar waren.In version 1.0 and 1.1 of the .NET Framework, creating serializable types that would be reusable from one version of an application to the next was problematic. Wenn ein Typ durch Hinzufügen eines zusätzlicher Felder geändert wurde, traten die folgenden Probleme auf:If a type was modified by adding extra fields, the following problems would occur:

  • Ältere Versionen einer Anwendung lösten bei dem Versuch, neue Versionen des alten Typs zu deserialisieren, Ausnahmen aus.Older versions of an application would throw exceptions when asked to deserialize new versions of the old type.

  • Neuere Versionen einer Anwendung lösten bei dem Versuch, ältere Versionen eines Typs mit fehlenden Daten zu deserialisieren, Ausnahmen aus.Newer versions of an application would throw exceptions when deserializing older versions of a type with missing data.

Bei VTS (Version Tolerant Serialization) handelt es sich um eine Gruppe von Funktionen, die in .NET Framework 2.0 eingeführt wurde, um das möglicherweise im Laufe der Zeit erforderliche Ändern serialisierbarer Typen zu vereinfachen.Version Tolerant Serialization (VTS) is a set of features introduced in .NET Framework 2.0 that makes it easier, over time, to modify serializable types. Die VTS-Funktionen sind insbesondere für Klassen aktiviert, auf die das SerializableAttribute-Attribut angewendet wurde, einschließlich generischer Typen.Specifically, the VTS features are enabled for classes to which the SerializableAttribute attribute has been applied, including generic types. VTS ermöglicht das Hinzufügen neuer Felder zu diesen Klassen, ohne die Kompatibilität mit anderen Versionen des Typs zu beeinträchtigen.VTS makes it possible to add new fields to those classes without breaking compatibility with other versions of the type. Informationen zu einer funktionierenden Beispielanwendung finden Sie unter Technologiebeispiel für versionstolerante Serialisierung.For a working sample application, see Version Tolerant Serialization Technology Sample.

Die VTS-Funktionen werden bei der Verwendung von BinaryFormatter aktiviert.The VTS features are enabled when using the BinaryFormatter. Zudem sind alle Funktionen mit Ausnahme der Toleranz für externe Daten auch bei der Verwendung von SoapFormatter aktiviert.Additionally, all features except extraneous data tolerance are also enabled when using the SoapFormatter. Weitere Informationen zur Verwendung dieser Klassen für die Serialisierung finden Sie unter Binäre Serialisierung.For more information about using these classes for serialization, see Binary Serialization.

Warnung

Die binäre Serialisierung kann gefährlich sein.Binary serialization can be dangerous. Deserialisieren Sie niemals Daten aus nicht vertrauenswürdigen Quellen, und führen Sie niemals eine Schleife für serialisierte Daten in Systeme durch, die Sie nicht steuern.Never deserialize data from an untrusted source and never round-trip serialized data to systems not under your control.

FunktionslisteFeature list

VTS umfasst die folgenden Funktionen:The set of features includes the following:

  • Toleranz für externe oder unerwartete Daten.Tolerance of extraneous or unexpected data. Dies ermöglicht es neueren Versionen des Typs, Daten an frühere Versionen zu senden.This enables newer versions of the type to send data to older versions.

  • Toleranz für fehlende optionale Daten.Tolerance of missing optional data. Dies ermöglicht es älteren Versionen, Daten an neuere Versionen zu senden.This enables older versions to send data to newer versions.

  • Serialisierungsrückrufe.Serialization callbacks. Dies ermöglicht ein intelligentes Festlegen von Standardwerten im Fall fehlender Daten.This enables intelligent default value setting in cases where data is missing.

Zudem ist eine Funktion zum Deklarieren verfügbar, wenn ein neues optionales Feld hinzugefügt wurde.In addition, there is a feature for declaring when a new optional field has been added. Es handelt sich hierbei um die VersionAdded-Eigenschaft des OptionalFieldAttribute-Attributs.This is the VersionAdded property of the OptionalFieldAttribute attribute.

Diese Funktionen werden nachfolgend näher erläutert.These features are discussed in greater detail below.

Toleranz für externe oder unerwartete DatenTolerance of extraneous or unexpected data

In früheren Versionen wurden während der Deserialisierung bei auftretenden externen oder unerwarteten Daten Ausnahmen.In the past, during deserialization, any extraneous or unexpected data caused exceptions to be thrown. Mit VTS werden in derselben Situation keine Ausnahmen mehr ausgelöst, sondern alle externen oder unerwarteten Daten werden ignoriert.With VTS, in the same situation, any extraneous or unexpected data is ignored instead of causing exceptions to be thrown. Dies ermöglicht es, Anwendungen mit neueren Versionen eines Typs (d. h. eine Version mit mehr Feldern), Informationen an Anwendungen zu senden, die ältere Versionen desselben Typs erwarten.This enables applications that use newer versions of a type (that is, a version that includes more fields) to send information to applications that expect older versions of the same type.

Im folgenden Beispiel werden die zusätzlichen Daten im CountryField-Feld von Version 2.0 der Address-Klasse ignoriert, wenn eine ältere Anwendung die neuere Version deserialisiert.In the following example, the extra data contained in the CountryField of version 2.0 of the Address class is ignored when an older application deserializes the newer version.

// Version 1 of the Address class.  
[Serializable]  
public class Address  
{  
    public string Street;  
    public string City;  
}  
// Version 2.0 of the Address class.  
[Serializable]  
public class Address  
{  
    public string Street;  
    public string City;  
    // The older application ignores this data.  
    public string CountryField;  
}  
' Version 1 of the Address class.  
<Serializable> _  
Public Class Address  
    Public Street As String  
    Public City As String  
End Class  
  
' Version 2.0 of the Address class.  
<Serializable> _  
Public Class Address  
    Public Street As String  
    Public City As String  
    ' The older application ignores this data.  
    Public CountryField As String  
End Class  

Toleranz für fehlende DatenTolerance of missing data

Felder können mithilfe des OptionalFieldAttribute-Attributs als optional markiert werden.Fields can be marked as optional by applying the OptionalFieldAttribute attribute to them. Wenn während der Deserialisierung optionale Daten fehlen, ignoriert die Serialisierungs-Engine das Fehlen dieser Daten und löst keine Ausnahme aus.During deserialization, if the optional data is missing, the serialization engine ignores the absence and does not throw an exception. Anwendungen, die ältere Versionen eines Typs erwarten, können daher Daten an Anwendungen senden, die neuere Versionen desselben Typs erwarten.Thus, applications that expect older versions of a type can send data to applications that expect newer versions of the same type.

Im folgenden Beispiel wird Version&#160;2.0 der Address-Klasse mit dem als optional markierten CountryField-Feld veranschaulicht.The following example shows version 2.0 of the Address class with the CountryField field marked as optional. Wenn eine ältere Anwendung Version&#160;1 an eine neuere Anwendung sendet, die Version&#160;2.0 erwartet, wird das Fehlen der Daten ignoriert.If an older application sends version 1 to a newer application that expects version 2.0, the absence of the data is ignored.

[Serializable]  
public class Address  
{  
    public string Street;  
    public string City;  
  
    [OptionalField]  
    public string CountryField;  
}  
<Serializable> _  
Public Class Address  
    Public Street As String  
    Public City As String  
  
    <OptionalField> _  
    Public CountryField As String  
End Class  

SerialisierungsrückrufeSerialization callbacks

Serialisierungsrückrufe stellen einen Mechanismus dar, der an vier Punkten im Serialisierungs-/Deserialisierungsprozess Hooks bereitstellt.Serialization callbacks are a mechanism that provides hooks into the serialization/deserialization process at four points.

AttributAttribute Beim Aufruf der verknüpften MethodeWhen the Associated Method is Called Typische VerwendungTypical Use
OnDeserializingAttribute Vor der Deserialisierung. *Before deserialization.* Initialisieren von Standardwerten für optionale Felder.Initialize default values for optional fields.
OnDeserializedAttribute Nach der Deserialisierung.After deserialization. Korrigieren Sie optionale Feldwerte auf der Grundlage des Inhalts anderer Felder.Fix optional field values based on contents of other fields.
OnSerializingAttribute Vor der Deserialisierung.Before serialization. Vorbereiten der Serialisierung.Prepare for serialization. Erstellen Sie z.&#160;B. optionale Datenstrukturen.For example, create optional data structures.
OnSerializedAttribute Nach der Serialisierung.After serialization. Protokollieren der Serialisierungsereignisse.Log serialization events.

* Dieser Rückruf wird vor dem Deserialisierungskonstruktor aufgerufen, sofern ein solcher vorhanden ist.* This callback is invoked before the deserialization constructor, if one is present.

Verwenden von RückrufenUsing callbacks

Zur Verwendung von Rückrufen wenden Sie die entsprechenden Attribute auf eine Methode an, die einen StreamingContext-Parameter akzeptiert.To use callbacks, apply the appropriate attribute to a method that accepts a StreamingContext parameter. Mit jedem dieser Attribute kann nur eine Methode pro Klasse markiert werden.Only one method per class can be marked with each of these attributes. Zum Beispiel:For example:

[OnDeserializing]  
private void SetCountryRegionDefault(StreamingContext sc)  
{  
    CountryField = "Japan";  
}  
<OnDeserializing>  
Private Sub SetCountryRegionDefault(StreamingContext sc)  
    CountryField = "Japan";  
End Sub  

Diese Methoden sind für die Versionsverwaltung vorgesehen.The intended use of these methods is for versioning. Während der Deserialisierung wird ein optionales Feld möglicherweise nicht korrekt initialisiert, wenn die Daten für das Feld fehlen.During deserialization, an optional field may not be correctly initialized if the data for the field is missing. Dies kann korrigiert werden, indem zunächst die Methode erstellt wird, die den richtigen Wert zuordnet, und dann entweder das OnDeserializingAttribute- oder OnDeserializedAttribute-Attribut auf die Methode angewendet wird.This can be corrected by creating the method that assigns the correct value, then applying either the OnDeserializingAttribute or OnDeserializedAttribute attribute to the method.

Im folgenden Beispiel wird die Methode im Kontext eines Typs veranschaulicht.The following example shows the method in the context of a type. Wenn eine frühere Version einer Anwendung eine Instanz derAddress-Klasse an eine höhere Version der Anwendung sendet, fehlen Daten im CountryField-Feld.If an earlier version of an application sends an instance of the Address class to a later version of the application, the CountryField field data will be missing. Nach der Deserialisierung wird das Feld jedoch auf den Standardwert "Japan" festgelegt.But after deserialization, the field will be set to a default value "Japan."

[Serializable]  
public class Address  
{  
    public string Street;  
    public string City;  
    [OptionalField]  
    public string CountryField;  
  
    [OnDeserializing]  
    private void SetCountryRegionDefault (StreamingContext sc)  
    {  
        CountryField = "Japan";  
    }  
}  
<Serializable> _  
Public Class Address  
    Public Street As String  
    Public City As String  
    <OptionalField> _  
    Public CountryField As String  
  
    <OnDeserializing> _  
    Private Sub SetCountryRegionDefault(StreamingContext sc)  
        CountryField = "Japan";  
    End Sub  
End Class  

Die VersionAdded-EigenschaftThe VersionAdded property

Das OptionalFieldAttribute verfügt über die VersionAdded-Eigenschaft.The OptionalFieldAttribute has the VersionAdded property. In Version 2.0 von .NET Framework wird diese nicht verwendet.In version 2.0 of the .NET Framework, this isn't used. Es ist jedoch wichtig, dass diese Eigenschaft richtig festgelegt wird, um sicherzustellen, dass der Typ mit zukünftigen Serialisierungs-Engines kompatibel ist.However, it's important to set this property correctly to ensure that the type will be compatible with future serialization engines.

Die Eigenschaft gibt an, welche Version eines Typs einem bestimmten Feld hinzugefügt wurde.The property indicates which version of a type a given field has been added. Sie sollte bei jeder Änderung des Typs um genau 1 erhöht werden (ausgehend von 2). Dies veranschaulicht das folgende Beispiel:It should be incremented by exactly one (starting at 2) every time the type is modified, as shown in the following example:

// Version 1.0  
[Serializable]  
public class Person  
{  
    public string FullName;  
}  
  
// Version 2.0  
[Serializable]  
public class Person  
{  
    public string FullName;  
  
    [OptionalField(VersionAdded = 2)]  
    public string NickName;  
    [OptionalField(VersionAdded = 2)]  
    public DateTime BirthDate;  
}  
  
// Version 3.0  
[Serializable]  
public class Person  
{  
    public string FullName;  
  
    [OptionalField(VersionAdded=2)]  
    public string NickName;  
    [OptionalField(VersionAdded=2)]  
    public DateTime BirthDate;  
  
    [OptionalField(VersionAdded=3)]  
    public int Weight;  
}  
' Version 1.0  
<Serializable> _  
Public Class Person  
    Public FullName  
End Class  
  
' Version 2.0  
<Serializable> _  
Public Class Person  
    Public FullName As String  
  
    <OptionalField(VersionAdded := 2)> _  
    Public NickName As String  
    <OptionalField(VersionAdded := 2)> _  
    Public BirthDate As DateTime  
End Class  
  
' Version 3.0  
<Serializable> _  
Public Class Person  
    Public FullName As String  
  
    <OptionalField(VersionAdded := 2)> _  
    Public NickName As String  
    <OptionalField(VersionAdded := 2)> _  
    Public BirthDate As DateTime  
  
    <OptionalField(VersionAdded := 3)> _  
    Public Weight As Integer  
End Class  

SerializationBinderSerializationBinder

Einige Benutzer müssen möglicherweise steuern, welche Klasse serialisiert und deserialisiert werden soll, da unterschiedliche Versionen der Klasse auf dem Server und Client erforderlich ist.Some users may need to control which class to serialize and deserialize because a different version of the class is required on the server and client. SerializationBinder ist eine abstrakte Klasse, mit der die tatsächlichen Typen gesteuert werden, die während der Serialisierung und Deserialisierung verwendet werden.SerializationBinder is an abstract class used to control the actual types used during serialization and deserialization. Wenn Sie diese Klasse verwenden möchten, müssen Sie eine Klasse von SerializationBinder ableiten und die BindToName-Methode und die BindToType-Methode überschreiben.To use this class, derive a class from SerializationBinder and override the BindToName and BindToType methods. Weitere Informationen finden Sie unter Steuern der Serialisierung und Deserialisierung mit SerializationBinder.For more information, see Controlling Serialization and Deserialization with SerializationBinder.

Bewährte MethodenBest practices

Um das richtige Versionsverhalten sicherzustellen, beachten Sie beim Ändern eines Typs von Version zu Version die folgenden Regeln:To ensure proper versioning behavior, follow these rules when modifying a type from version to version:

  • Entfernen Sie nie ein serialisiertes Feld.Never remove a serialized field.

  • Wenden Sie das NonSerializedAttribute-Attribut nie auf ein Feld an, wenn das Attribut in der vorherigen Version nicht auf das Feld angewendet wurde.Never apply the NonSerializedAttribute attribute to a field if the attribute was not applied to the field in the previous version.

  • Ändern Sie nie den Namen oder den Typ eines serialisierten Felds.Never change the name or the type of a serialized field.

  • Wenden Sie beim Hinzufügen eines neuen serialisierten Felds das OptionalFieldAttribute-Attribut an.When adding a new serialized field, apply the OptionalFieldAttribute attribute.

  • Wenden Sie beim Entfernen eines NonSerializedAttribute-Attributs von einem Feld, das in einer vorherigen Version nicht serialisierbar war, das OptionalFieldAttribute-Attribut an.When removing a NonSerializedAttribute attribute from a field (that was not serializable in a previous version), apply the OptionalFieldAttribute attribute.

  • Legen Sie für alle optionalen Felder sinnvolle Standardwerte fest, indem Sie die Serialisierungsrückrufe verwenden, sofern 0 oder NULL nicht als Standardwerte zulässig sind.For all optional fields, set meaningful defaults using the serialization callbacks unless 0 or null as defaults are acceptable.

Um sicherzustellen, dass ein Typ mit zukünftigen Serialisierungs-Engines kompatibel ist, beachten Sie die folgenden Richtlinien:To ensure that a type will be compatible with future serialization engines, follow these guidelines:

  • Legen Sie die VersionAdded-Eigenschaft im OptionalFieldAttribute-Attribut ordnungsgemäß fest.Always set the VersionAdded property on the OptionalFieldAttribute attribute correctly.

  • Vermeiden Sie verzweigte Versionen.Avoid branched versioning.

Siehe auchSee also