Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
In diesem Thema werden die bewährten Methoden zum Erstellen von Datenverträgen aufgeführt, die sich im Laufe der Zeit leicht entwickeln können. Weitere Informationen zu Datenverträgen finden Sie in den Themen unter Verwendung von Datenverträgen.
Hinweis zur Schemaüberprüfung
Bei der Erläuterung der Datenvertragsversionsverwaltung ist es wichtig zu beachten, dass das datenvertragsschema, das von Windows Communication Foundation (WCF) exportiert wurde, keine Versionsverwaltungsunterstützung hat, außer dass Elemente standardmäßig als optional gekennzeichnet sind.
Dies bedeutet, dass selbst das am häufigsten verwendete Versionsverwaltungsszenario, z. B. das Hinzufügen eines neuen Datenelements, nicht in einer Weise implementiert werden kann, die sich nahtlos auf ein bestimmtes Schema bezieht. Die neueren Versionen eines Datenvertrags (z. B. mit einem neuen Datenmitglied) lassen sich nicht durch das alte Schema validieren.
Es gibt jedoch viele Szenarien, in denen strenge Schemakompatibilität nicht erforderlich ist. Viele Webdienstplattformen, einschließlich WCF- und XML-Webdiensten, die mit ASP.NET erstellt wurden, führen standardmäßig keine Schemaüberprüfung durch und tolerieren daher zusätzliche Elemente, die nicht vom Schema beschrieben werden. Bei der Arbeit mit solchen Plattformen sind viele Versionsverwaltungsszenarien einfacher zu implementieren.
Daher gibt es zwei Richtlinien für die Datenvertragsversionsverwaltung: einen Satz für Szenarien, in denen strenge Schemagültigkeit wichtig ist, und ein weiterer Satz für Szenarien, wenn dies nicht der Fall ist.
Versionsverwaltung, wenn die Schemaüberprüfung erforderlich ist
Wenn strenge Schemagültigkeit in alle Richtungen (neu-zu-alt und alt-neu) erforderlich ist, sollten Datenverträge als unveränderlich betrachtet werden. Wenn die Versionsverwaltung erforderlich ist, sollte ein neuer Datenvertrag mit einem anderen Namen oder Namespace erstellt werden, und der Dienstvertrag mit dem Datentyp sollte entsprechend versioniert werden.
Beispielsweise nimmt ein Servicevertrag zur Bestellabwicklung namens PoProcessing
mit einer PostPurchaseOrder
-Operation einen Parameter an, der einem PurchaseOrder
-Datenvertrag entspricht. Wenn sich der PurchaseOrder
Vertrag ändern muss, müssen Sie einen neuen Datenvertrag erstellen, d. h., PurchaseOrder2
der die Änderungen enthält. Anschließend müssen Sie die Versionsverwaltung auf Dienstvertragsebene behandeln. Beispielsweise durch Erstellen eines PostPurchaseOrder2
Vorgangs, der den PurchaseOrder2
Parameter verwendet, oder durch Erstellen eines PoProcessing2
Dienstvertrags, in dem der PostPurchaseOrder
Vorgang einen PurchaseOrder2
Datenvertrag akzeptiert.
Beachten Sie, dass Änderungen an Datenverträgen, die von anderen Datenverträgen referenziert werden, sich auch auf die Ebene des Servicemodells auswirken. Im vorherigen Szenario muss der PurchaseOrder
Datenvertrag beispielsweise nicht geändert werden. Sie enthält jedoch ein Datenmitglied eines Customer
-Datenvertrags, der wiederum ein Datenmitglied des Address
-Datenvertrags enthält, das geändert werden muss. In diesem Fall müssten Sie einen Address2
Datenvertrag mit den erforderlichen Änderungen erstellen, einen Customer2
Datenvertrag, der das Address2
Datenmitglied enthält, und einen PurchaseOrder2
Datenvertrag, der ein Customer2
Datenmitglied enthält. Wie im vorherigen Fall müsste auch der Servicevertrag versioniert werden.
Obwohl in diesen Beispielen Namen geändert werden (durch Anfügen eines "2"), empfiehlt es sich, Namespaces anstelle von Namen zu ändern, indem neue Namespaces mit einer Versionsnummer oder einem Datum angefügt werden. Beispielsweise würde sich der http://schemas.contoso.com/2005/05/21/PurchaseOrder
Datenvertrag in den http://schemas.contoso.com/2005/10/14/PurchaseOrder
Datenvertrag ändern.
Weitere Informationen finden Sie unter Best Practices: Dienstversionsverwaltung.
Gelegentlich müssen Sie eine strikte Schemakompatibilität für Nachrichten garantieren, die von Ihrer Anwendung gesendet werden, können sich jedoch nicht darauf verlassen, dass eingehende Nachrichten streng schemakonform sind. In diesem Fall besteht die Gefahr, dass eine eingehende Nachricht möglicherweise überflüssige Daten enthält. Die zusätzlichen Werte werden von WCF gespeichert und zurückgegeben und führen dazu, dass schema-ungültige Nachrichten gesendet werden. Um dieses Problem zu vermeiden, sollte das Roundtripping-Feature deaktiviert werden. Es gibt zwei Möglichkeiten, dies zu tun.
Implementieren Sie die IExtensibleDataObject Schnittstelle nicht für jeden Ihrer Typen.
Wenden Sie ein ServiceBehaviorAttribute-Attribut auf Ihren Dienstvertrag an, indem die IgnoreExtensionDataObject-Eigenschaft auf
true
festgelegt wird.
Weitere Informationen zum Roundtripping finden Sie unter Aufwärtskompatible Datenverträge.
Versionsverwaltung, wenn die Schemaüberprüfung nicht erforderlich ist
Strenge Schemakompatibilität ist selten erforderlich. Viele Plattformen tolerieren zusätzliche Elemente, die nicht durch ein Schema beschrieben werden. Solange dies toleriert ist, können die vollständigen Features verwendet werden, die in der Datenvertragsversionsverwaltung und Forward-Compatible Datenverträge beschrieben sind. Die folgenden Richtlinien werden empfohlen.
Einige der Richtlinien müssen genau befolgt werden, um neue Versionen eines Typs zu senden, bei denen eine ältere Version erwartet wird oder eine alte, wo die neue erwartet wird. Andere Richtlinien sind nicht unbedingt erforderlich, werden hier jedoch aufgeführt, da sie möglicherweise von der zukünftigen Schemaversionsverwaltung betroffen sind.
Versuchen Sie nicht, Datenverträge nach Typvererbung zu versionieren. Wenn Sie spätere Versionen erstellen möchten, ändern Sie entweder den Datenvertrag für einen vorhandenen Typ, oder erstellen Sie einen neuen nicht verknüpften Typ.
Die Verwendung der Vererbung zusammen mit Datenverträgen ist zulässig, sofern die Vererbung nicht als Versionsverwaltungsmechanismus verwendet wird und dass bestimmte Regeln befolgt werden. Wenn ein Typ von einem bestimmten Basistyp abgeleitet wird, sollte er in einer zukünftigen Version nicht von einem anderen Basistyp abgeleitet werden, es sei denn, er hat denselben Datenvertrag. Es gibt eine Ausnahme: Sie können einen Typ in die Hierarchie zwischen einem Datenvertragstyp und seinem Basistyp einfügen, aber nur, wenn er keine Datenmember mit denselben Namen wie andere Member in allen möglichen Versionen der anderen Typen in der Hierarchie enthält. Im Allgemeinen kann die Verwendung von Datenmembern mit denselben Namen auf unterschiedlichen Ebenen derselben Vererbungshierarchie zu schwerwiegenden Versionsverwaltungsproblemen führen und vermieden werden.
Implementieren Sie immer das IExtensibleDataObject, indem Sie mit der ersten Version eines Datenvertrags beginnen, um Roundtrips zu aktivieren. Weitere Informationen finden Sie unter Forward-Compatible Datenverträge. Wenn Sie eine oder mehrere Versionen eines Typs veröffentlicht haben, ohne diese Schnittstelle zu implementieren, implementieren Sie sie in der nächsten Version des Typs.
Ändern Sie in späteren Versionen nicht den Namen oder den Namespace des Datenvertrags. Wenn Sie den Namen oder den Namespace des Typs ändern, der dem Datenvertrag zugrunde liegt, achten Sie darauf, den Namen des Datenvertrags und den Namespace mithilfe der entsprechenden Mechanismen, wie der Name-Eigenschaft der DataContractAttribute, beizubehalten. Weitere Informationen zum Benennen finden Sie unter "Datenvertragsnamen".
Ändern Sie in späteren Versionen nicht die Namen von Datenmitgliedern. Wenn Sie den Namen des Felds, der Eigenschaft oder des Ereignisses ändern, das dem Datenelement zugrunde liegt, verwenden Sie die
Name
Eigenschaft des DataMemberAttribute Elements, um den vorhandenen Datenmememmnamen beizubehalten.Ändern Sie in späteren Versionen nicht den Typ eines Felds, einer Eigenschaft oder eines Ereignisses, das einem Datenmememm zugrunde liegt, so, dass sich der resultierende Datenvertrag für dieses Datenelement ändert. Beachten Sie, dass Schnittstellentypen für die Bestimmung des erwarteten Datenvertrags gleichwertig Object sind.
Ändern Sie in späteren Versionen nicht die Reihenfolge der vorhandenen Datenmitglieder, indem Sie die Order Eigenschaft des DataMemberAttribute Attributs anpassen.
In späteren Versionen können neue Datenmitglieder hinzugefügt werden. Sie sollten immer die folgenden Regeln einhalten:
Die IsRequired-Eigenschaft sollte immer auf dem Standardwert
false
bleiben.Wenn ein Standardwert von
null
oder 0 für das Mitglied inakzeptabel ist, sollte mithilfe von OnDeserializingAttribute eine Rückrufmethode bereitgestellt werden, um einen angemessenen Standardwert bereitzustellen, falls das Mitglied nicht im eingehenden Datenstrom vorhanden ist. Weitere Informationen über den Callback finden Sie unter Version-Tolerant Serialisierungs-Callbacks.Die DataMemberAttribute.Order Eigenschaft sollte verwendet werden, um sicherzustellen, dass alle neu hinzugefügten Datenmitglieder nach den vorhandenen Datenmitgliedern erscheinen. Die empfohlene Vorgehensweise lautet wie folgt: Für keinen Datenmember der ersten Version eines Datenvertrags sollte die
Order
-Eigenschaft festgelegt sein. Sie sollten für alle Datenmember, die Sie in Version 2 des Datenvertrags hinzugefügt haben, dieOrder
-Eigenschaft auf "2" festlegen. Alle in Version 3 des Datenvertrags hinzugefügten Datenmitglieder sollten ihrenOrder
auf 3 festgelegt haben, und so weiter. Es ist zulässig, mehrere Datenmember auf die gleicheOrder
-Nummer festzulegen.
Entfernen Sie Datenmember in höheren Versionen auch dann nicht, wenn die IsRequired-Eigenschaft in den vorherigen Versionen auf der Standardeinstellung
false
belassen wurde.Ändern Sie die
IsRequired
-Eigenschaft bei bestehenden Datenmitgliedern nicht von Version zu Version.Ändern Sie die
IsRequired
-Eigenschaft für erforderliche Datenmitglieder (wotrue
EmitDefaultValue
ist) nicht von Version zu Version.Versuchen Sie nicht, verzweigte Versionsverwaltungshierarchien zu erstellen. Das heißt, es sollte immer ein Pfad in mindestens einer Richtung von jeder Version zu jeder anderen Version vorhanden sein, wobei nur die von diesen Richtlinien zulässigen Änderungen verwendet werden.
Wenn beispielsweise Version 1 eines Personendatenvertrags nur das Namensdatenelement enthält, sollten Sie keine Version 2a des Vertrags erstellen, die nur das Altersdatenelement hinzufügt, und keine Version 2b, die nur das Adressdatenelement hinzufügt. Der Übergang von 2a zu 2b würde das Entfernen von "Age" und das Hinzufügen von "Address" umfassen. Ein Übergang in der anderen Richtung würde hingegen das Entfernen von "Address" und das Hinzufügen von "Age" umfassen. Das Entfernen von Mitgliedern ist durch diese Richtlinien nicht zulässig.
Sie sollten in der Regel keine neuen Untertypen vorhandener Datentypen in einer neuen Version Ihrer Anwendung erstellen. Ebenso sollten Sie keine neuen Datenverträge erstellen, die anstelle von Datenmmbern verwendet werden, die als Objekt oder als Schnittstellentypen deklariert sind. Das Erstellen dieser neuen Klassen ist nur zulässig, wenn Sie wissen, dass Sie die neuen Typen zur Liste bekannter Typen aller Instanzen Ihrer alten Anwendung hinzufügen können. In Version 1 Ihrer Anwendung haben Sie möglicherweise einen Datenvertragstyp "LibraryItem" mit den Untertypen "Buch" und "Zeitung". LibraryItem würde dann eine bekannte Typenliste haben, die "Book" und "Zeitung" enthält. Angenommen, Sie fügen jetzt einen Magazintyp in Version 2 hinzu, bei dem es sich um einen Untertyp von LibraryItem handelt. Wenn Sie eine Magazine-Instanz von Version 2 an Version 1 senden, ist der Magazindatenvertrag nicht in der Liste der bekannten Typen enthalten, wodurch eine Ausnahme ausgelöst wird.
Sie sollten keine Enumerationselemente zwischen Versionen hinzufügen oder entfernen. Sie sollten auch keine Enumerationsmitglieder umbenennen, es sei denn, Sie verwenden die Eigenschaft ‚Name’ für das
EnumMemberAttribute
Attribut, um ihre Namen im Datenvertragsmodell gleich zu lassen.Sammlungen können im Datenvertragsmodell austauschbar sein, wie in Sammlungstypen in Datenverträgen beschrieben. Dies ermöglicht ein hohes Maß an Flexibilität. Stellen Sie jedoch sicher, dass Sie einen Sammlungstyp nicht versehentlich auf nicht austauschbare Weise von Version zu Version ändern. Ändern Sie z. B. nicht von einer nicht angepassten Auflistung (d. h. ohne das
CollectionDataContractAttribute
Attribut) zu einer angepassten oder einer angepassten Auflistung zu einer nicht angepassten Auflistung. Ändern Sie außerdem die Eigenschaften aufCollectionDataContractAttribute
nicht von Version zu Version. Die einzige zulässige Änderung besteht darin, eine Name- oder Namespaceeigenschaft hinzuzufügen, wenn sich der Name oder Namespace des zugrunde liegenden Sammlungstyps geändert hat und Sie den Datenvertragsnamen und den Namespace wie in einer früheren Version festlegen müssen.
Einige der hier aufgeführten Richtlinien können sicher ignoriert werden, wenn spezielle Umstände gelten. Stellen Sie sicher, dass Sie die serialisierungs-, Deserialisierungs- und Schemamechanismen kennen, bevor Sie von den Richtlinien abweichen.
Siehe auch
- Name
- DataContractAttribute
- Order
- IsRequired
- IExtensibleDataObject
- ServiceBehaviorAttribute
- ExtensionData
- ExtensionDataObject
- OnDeserializingAttribute
- Verwenden von Datenverträgen
- Datenvertragsversionsverwaltung
- Datenvertragsnamen
- Forward-Compatible Datenverträge
- Versionstolerante Serialisierungsrückrufe