Delen via


Aanbevolen procedures: Versiebeheer van gegevenscontract

In dit onderwerp vindt u de aanbevolen procedures voor het maken van gegevenscontracten die in de loop van de tijd eenvoudig kunnen worden ontwikkeld. Zie de onderwerpen in Data Contracts gebruiken voor meer informatie over gegevenscontracten.

Opmerking over schemavalidatie

Bij het bespreken van versiebeheer voor gegevenscontracten is het belangrijk te weten dat het datacontractschema dat door Windows Communication Foundation (WCF) wordt geëxporteerd, geen ondersteuning voor versiebeheer heeft, behalve het feit dat elementen standaard als optioneel zijn gemarkeerd.

Dit betekent dat zelfs het meest voorkomende versiebeheerscenario, zoals het toevoegen van een nieuw gegevenslid, niet kan worden geïmplementeerd op een manier die naadloos is met betrekking tot een bepaald schema. De nieuwere versies van een gegevenscontract (bijvoorbeeld met een nieuw gegevenslid) valideren niet met behulp van het oude schema.

Er zijn echter veel scenario's waarin strikte schemacompatibiliteit niet vereist is. Veel webservicesplatformen, waaronder WCF- en XML-webservices die zijn gemaakt met ASP.NET, voeren standaard geen schemavalidatie uit en tolereren daarom extra elementen die niet door het schema worden beschreven. Wanneer u met dergelijke platforms werkt, zijn veel versiebeheerscenario's eenvoudiger te implementeren.

Er zijn dus twee sets richtlijnen voor versiebeheer van gegevenscontracten: één set voor scenario's waarbij strikte geldigheid van het schema belangrijk is en een andere set voor scenario's wanneer dat niet het geval is.

Versiebeheer wanneer schemavalidatie is vereist

Als strikte schemavalidatie vereist is in alle richtingen (nieuw-op-oud en oud-naar-nieuw), moeten gegevenscontracten als onveranderbaar worden beschouwd. Als versiebeheer vereist is, moet er een nieuw gegevenscontract worden gemaakt, met een andere naam of naamruimte, en moet het servicecontract met behulp van het gegevenstype dienovereenkomstig worden geversied.

Een servicecontract PoProcessing voor de verwerking van inkooporders met een PostPurchaseOrder bewerking gebruikt bijvoorbeeld een parameter die voldoet aan een PurchaseOrder gegevenscontract. Als het PurchaseOrder contract moet worden gewijzigd, moet u een nieuw gegevenscontract maken, dat wil zeggen, PurchaseOrder2met daarin de wijzigingen. Vervolgens moet u de versiebeheer op servicecontractniveau afhandelen. Bijvoorbeeld door een PostPurchaseOrder2 bewerking te maken die de PurchaseOrder2 parameter gebruikt of door een PoProcessing2 servicecontract te maken waarin de PostPurchaseOrder bewerking een PurchaseOrder2 gegevenscontract gebruikt.

Houd er rekening mee dat wijzigingen in gegevenscontracten waarnaar wordt verwezen door andere gegevenscontracten, ook worden uitgebreid naar de servicemodellaag. In het vorige scenario hoeft het PurchaseOrder gegevenscontract bijvoorbeeld niet te worden gewijzigd. Het bevat echter een gegevenslid van een Customer gegevenscontract, dat op zijn beurt een gegevenslid van het Address gegevenscontract bevat, dat wel moet worden gewijzigd. In dat geval moet u een Address2 gegevenscontract maken met de vereiste wijzigingen, een Customer2 gegevenscontract dat het Address2 gegevenslid bevat en een PurchaseOrder2 gegevenscontract dat een Customer2 gegevenslid bevat. Net als in het vorige geval moet het servicecontract ook worden geversied.

Hoewel in deze voorbeelden namen worden gewijzigd (door een '2' toe te voegen), is het raadzaam om naamruimten te wijzigen in plaats van namen door nieuwe naamruimten toe te voegen met een versienummer of een datum. Het gegevenscontract wordt bijvoorbeeld http://schemas.contoso.com/2005/05/21/PurchaseOrder gewijzigd in het http://schemas.contoso.com/2005/10/14/PurchaseOrder gegevenscontract.

Zie Aanbevolen procedures voor serviceversiebeheer voor meer informatie.

Af en toe moet u strikte schemanaleving garanderen voor berichten die door uw toepassing worden verzonden, maar u kunt niet vertrouwen op de binnenkomende berichten om strikt schema-compatibel te zijn. In dit geval bestaat er een gevaar dat een binnenkomend bericht overbodige gegevens kan bevatten. De overbodige waarden worden opgeslagen en geretourneerd door WCF en leiden er dus toe dat schema-ongeldige berichten worden verzonden. Om dit probleem te voorkomen, moet de retourfunctie worden uitgeschakeld. Er zijn twee manieren om dit te doen.

Zie Forward-Compatible Data Contracts voor meer informatie over round-tripping.

Versiebeheer wanneer schemavalidatie niet vereist is

Strikte schemacompatibiliteit is zelden vereist. Veel platforms verdragen extra elementen die niet worden beschreven door een schema. Zolang dit wordt getolereerd, kan de volledige set functies die worden beschreven in Data Contract Versioning en Forward-Compatible Data Contracts worden gebruikt. De volgende richtlijnen worden aanbevolen.

Sommige van de richtlijnen moeten exact worden gevolgd om nieuwe versies van een type te verzenden waarvan een oudere wordt verwacht of een oude te verzenden waar de nieuwe wordt verwacht. Andere richtlijnen zijn niet strikt vereist, maar worden hier vermeld omdat ze mogelijk worden beïnvloed door de toekomst van schemaversiebeheer.

  1. Probeer geen versie van gegevenscontracten te maken op basis van overname van het type. Als u latere versies wilt maken, wijzigt u het gegevenscontract voor een bestaand type of maakt u een nieuw niet-gerelateerd type.

  2. Het gebruik van overname in combinatie met gegevenscontracten is toegestaan, mits overname niet wordt gebruikt als versiebeheermechanisme en dat bepaalde regels worden gevolgd. Als een type is afgeleid van een bepaald basistype, moet u het niet afleiden van een ander basistype in een toekomstige versie (tenzij het hetzelfde gegevenscontract heeft). Er is één uitzondering hierop: u kunt een type invoegen in de hiërarchie tussen een gegevenscontracttype en het basistype ervan, maar alleen als deze geen gegevensleden bevat met dezelfde namen als andere leden in mogelijke versies van de andere typen in de hiërarchie. Over het algemeen kan het gebruik van gegevensleden met dezelfde namen op verschillende niveaus van dezelfde overnamehiërarchie leiden tot ernstige problemen met versiebeheer en moeten worden vermeden.

  3. Vanaf de eerste versie van een gegevenscontract moet u altijd implementeren IExtensibleDataObject om roundtripping mogelijk te maken. Zie Forward-Compatible Data Contracts voor meer informatie. Als u een of meer versies van een type hebt uitgebracht zonder deze interface te implementeren, implementeert u deze in de volgende versie van het type.

  4. Wijzig in latere versies de naam of naamruimte van het gegevenscontract niet. Als u de naam of naamruimte van het type onder het gegevenscontract wijzigt, moet u de naam en naamruimte van het gegevenscontract behouden met behulp van de juiste mechanismen, zoals de Name eigenschap van het DataContractAttributegegevenscontract. Zie Namen van gegevenscontract voor meer informatie over naamgeving.

  5. Wijzig in latere versies de namen van gegevensleden niet. Als u de naam van het veld, de eigenschap of de gebeurtenis die onder het gegevenslid ligt, wijzigt, gebruikt u de Name eigenschap van de eigenschap van het DataMemberAttribute gegevenslid om de bestaande naam van het gegevenslid te behouden.

  6. Wijzig in latere versies niet het type van een veld, eigenschap of gebeurtenis die onder een gegevenslid ligt, zodat het resulterende gegevenscontract voor dat gegevenslid wordt gewijzigd. Houd er rekening mee dat interfacetypen gelijk zijn aan Object voor het bepalen van het verwachte gegevenscontract.

  7. Wijzig in latere versies de volgorde van de bestaande gegevensleden niet door de Order eigenschap van het DataMemberAttribute kenmerk aan te passen.

  8. In latere versies kunnen nieuwe gegevensleden worden toegevoegd. Ze moeten altijd de volgende regels volgen:

    1. De IsRequired eigenschap moet altijd op de standaardwaarde van false.

    2. Als een standaardwaarde van null of nul voor het lid onaanvaardbaar is, moet een callback-methode worden opgegeven met behulp van de OnDeserializingAttribute methode om een redelijke standaardwaarde te bieden voor het geval het lid niet aanwezig is in de binnenkomende stroom. Zie Callbacks voor versietolerante serialisatie voor meer informatie over de callback.

    3. De DataMemberAttribute.Order eigenschap moet worden gebruikt om ervoor te zorgen dat alle nieuw toegevoegde gegevensleden worden weergegeven na de bestaande gegevensleden. De aanbevolen manier om dit te doen is als volgt: geen van de gegevensleden in de eerste versie van het gegevenscontract moet hun Order eigenschappen hebben ingesteld. Alle gegevensleden die zijn toegevoegd in versie 2 van het gegevenscontract, moeten hun Order eigenschap hebben ingesteld op 2. Alle gegevensleden die zijn toegevoegd in versie 3 van het gegevenscontract, moeten zijn Order ingesteld op 3, enzovoort. Het is toegestaan om meer dan één gegevenslid te laten instellen op hetzelfde Order getal.

  9. Verwijder geen gegevensleden in latere versies, zelfs niet als de eigenschap in eerdere versies op de standaardeigenschap van false de IsRequired eigenschap is gelaten.

  10. Wijzig de IsRequired eigenschap van bestaande gegevensleden niet van versie naar versie.

  11. Wijzig de EmitDefaultValue eigenschap niet van versie in versie voor vereiste gegevensleden (waar dat IsRequired wel istrue).

  12. Probeer geen vertakkingshiërarchieën voor versiebeheer te maken. Dat wil gezegd, er moet altijd een pad in ten minste één richting zijn van elke versie naar een andere versie met alleen de wijzigingen die door deze richtlijnen zijn toegestaan.

    Als bijvoorbeeld versie 1 van een persoonsgegevenscontract alleen het lid Naamgegevens bevat, moet u versie 2a van het contract niet maken en alleen het lid Leeftijd en versie 2b toevoegen. Als u van 2a naar 2b gaat, moet u leeftijd verwijderen en adres toevoegen; In de andere richting zou het verwijderen van adres en het toevoegen van leeftijd inhouden. Leden verwijderen is niet toegestaan door deze richtlijnen.

  13. Over het algemeen moet u geen nieuwe subtypen maken van bestaande gegevenscontracttypen in een nieuwe versie van uw toepassing. Op dezelfde manier moet u geen nieuwe gegevenscontracten maken die worden gebruikt in plaats van gegevensleden die zijn gedeclareerd als Object of als interfacetypen. Het maken van deze nieuwe klassen is alleen toegestaan wanneer u weet dat u de nieuwe typen kunt toevoegen aan de lijst met bekende typen van alle exemplaren van uw oude toepassing. In versie 1 van uw toepassing hebt u bijvoorbeeld het gegevenscontracttype LibraryItem met de subtypen Boek- en Krant-gegevenscontract. LibraryItem zou dan een lijst met bekende typen hebben die Boek en Krant bevat. Stel dat u nu een tijdschrifttype toevoegt in versie 2. Dit is een subtype van LibraryItem. Als u een Magazine-exemplaar verzendt van versie 2 naar versie 1, wordt het datacontract van Magazine niet gevonden in de lijst met bekende typen en wordt er een uitzondering gegenereerd.

  14. U mag geen opsommingsleden toevoegen of verwijderen tussen versies. U moet ook de naam van opsommingsleden niet wijzigen, tenzij u de eigenschap Naam op het EnumMemberAttribute kenmerk gebruikt om hun namen in het gegevenscontractmodel hetzelfde te houden.

  15. Verzamelingen zijn uitwisselbaar in het gegevenscontractmodel, zoals beschreven in verzamelingstypen in gegevenscontracten. Dit maakt een grote mate van flexibiliteit mogelijk. Zorg er echter voor dat u een verzamelingstype niet per ongeluk wijzigt op een niet-uitwisselbare manier van versie naar versie. Wijzig bijvoorbeeld niet van een niet-aangepaste verzameling (dat wil gezegd, zonder het CollectionDataContractAttribute kenmerk) in een aangepaste verzameling of een aangepaste verzameling in een niet-aangepaste verzameling. Wijzig ook niet de eigenschappen van de CollectionDataContractAttribute versie in versie. De enige toegestane wijziging is het toevoegen van een naam- of naamruimteeigenschap als de naam of naamruimte van het onderliggende verzamelingstype is gewijzigd en u de naam en naamruimte van het gegevenscontract hetzelfde moet maken als in een vorige versie.

Sommige van de hier vermelde richtlijnen kunnen veilig worden genegeerd wanneer er speciale omstandigheden van toepassing zijn. Zorg ervoor dat u de serialisatie-, deserialisatie- en schemamechanismen volledig begrijpt voordat u afwijkt van de richtlijnen.

Zie ook