Delen via


Surrogaten van gegevenscontract

Het gegevenscontract surrogaat is een geavanceerde functie die is gebaseerd op het Data Contract-model. Deze functie is ontworpen om te worden gebruikt voor het aanpassen en vervangen van typen in situaties waarin gebruikers willen wijzigen hoe een type wordt geserialiseerd, gedeserialiseerd of geprojecteerd in metagegevens. Sommige scenario's waarin een surrogaat kan worden gebruikt, is wanneer er geen gegevenscontract is opgegeven voor het type, worden velden en eigenschappen niet gemarkeerd met het DataMemberAttribute kenmerk of gebruikers willen dynamisch schemavariaties maken.

Serialisatie en deserialisatie worden uitgevoerd met de surrogaat van het gegevenscontract wanneer u DataContractSerializer deze gebruikt om te converteren van .NET Framework naar een geschikte indeling, zoals XML. Gegevenscontract surrogaat kan ook worden gebruikt om de metagegevens te wijzigen die zijn geëxporteerd voor typen, bij het produceren van metagegevensweergaven zoals XML-schemadocumenten (XSD). Bij het importeren wordt code gemaakt op basis van metagegevens en kan in dit geval ook de surrogaat worden gebruikt om de gegenereerde code aan te passen.

Hoe de surrogaat werkt

Een surrogaat werkt door één type (het oorspronkelijke type) toe te kennen aan een ander type (het type 'surrogated'). In het volgende voorbeeld ziet u het oorspronkelijke type Inventory en een nieuw surrogaattype InventorySurrogated . Het Inventory type is niet serialiseerbaar, maar het InventorySurrogated type is:

public class Inventory
{
    public int pencils;
    public int pens;
    public int paper;
}

Omdat er geen gegevenscontract is gedefinieerd voor deze klasse, converteert u de klasse naar een surrogaatklasse met een gegevenscontract. De surrogated klasse wordt weergegeven in het volgende voorbeeld:

[DataContract(Name = "Inventory")]
public class InventorySurrogated
{
    [DataMember]
    public int numpencils;
    [DataMember]
    public int numpaper;
    [DataMember]
    private int numpens;

    public int pens
    {
        get { return numpens; }
        set { numpens = value; }
    }
}

De IDataContractSurrogate implementeren

Als u de surrogaat voor het gegevenscontract wilt gebruiken, implementeert u de IDataContractSurrogate interface.

Hier volgt een overzicht van elke methode voor IDataContractSurrogate een mogelijke implementatie.

GetDataContractType

De GetDataContractType methode wijst het ene type toe aan het andere. Deze methode is vereist voor serialisatie, deserialisatie, importeren en exporteren.

De eerste taak is het definiëren van welke typen worden toegewezen aan andere typen. Voorbeeld:

public Type GetDataContractType(Type type)
{
    Console.WriteLine("GetDataContractType");
    if (typeof(Inventory).IsAssignableFrom(type))
    {
        return typeof(InventorySurrogated);
    }
    return type;
}
  • Bij serialisatie wordt de toewijzing die door deze methode wordt geretourneerd, vervolgens gebruikt om het oorspronkelijke exemplaar te transformeren naar een vervangen exemplaar door de GetObjectToSerialize methode aan te roepen.

  • Bij de deserialisatie wordt de toewijzing die door deze methode wordt geretourneerd, gebruikt door de serialisatiefunctie om te deserialiseren in een exemplaar van het surrogaattype. Vervolgens wordt aanroepen GetDeserializedObject om het vervangende exemplaar om te zetten in een exemplaar van het oorspronkelijke type.

  • Bij het exporteren wordt het surrogaattype dat door deze methode wordt geretourneerd, weergegeven om het gegevenscontract op te halen dat moet worden gebruikt voor het genereren van metagegevens.

  • Bij het importeren wordt het eerste type gewijzigd in een surrogaattype dat wordt weerspiegeld om het gegevenscontract te laten gebruiken voor doeleinden zoals verwijzingen naar ondersteuning.

De Type parameter is het type object dat wordt geserialiseerd, gedeserialiseerd, geïmporteerd of geëxporteerd. De GetDataContractType methode moet het invoertype retourneren als het surrogaat het type niet verwerkt. Anders retourneert u het juiste surrogated type. Als er verschillende surrogaattypen bestaan, kunnen er in deze methode talloze toewijzingen worden gedefinieerd.

De GetDataContractType methode wordt niet aangeroepen voor ingebouwde datacontractprimitief, zoals Int32 of String. Voor andere typen, zoals matrices, door de gebruiker gedefinieerde typen en andere gegevensstructuren, wordt deze methode aangeroepen voor elk type.

In het vorige voorbeeld controleert de methode of de type parameter vergelijkbaar Inventory is. Zo ja, dan wijst de methode deze toe aan InventorySurrogated. Wanneer een serialisatie,deserialisatie, importschema of exportschema wordt aangeroepen, wordt deze functie eerst aangeroepen om de toewijzing tussen typen te bepalen.

Methode GetObjectToSerialize

Met GetObjectToSerialize de methode wordt het oorspronkelijke typeexemplaren geconverteerd naar het exemplaar van het vervangen type. De methode is vereist voor serialisatie.

De volgende stap is het definiëren van de manier waarop de fysieke gegevens worden toegewezen van het oorspronkelijke exemplaar aan de surrogaat door de GetObjectToSerialize methode te implementeren. Voorbeeld:

public object GetObjectToSerialize(object obj, Type targetType)
{
    Console.WriteLine("GetObjectToSerialize");
    if (obj is Inventory)
    {
        InventorySurrogated isur = new InventorySurrogated();
        isur.numpaper = ((Inventory)obj).paper;
        isur.numpencils = ((Inventory)obj).pencils;
        isur.pens = ((Inventory)obj).pens;
        return isur;
    }
    return obj;
}

De GetObjectToSerialize methode wordt aangeroepen wanneer een object wordt geserialiseerd. Met deze methode worden gegevens van het oorspronkelijke type overgedragen naar de velden van het vervangende type. Velden kunnen rechtstreeks worden toegewezen aan surrogaatvelden of bewerkingen van de oorspronkelijke gegevens kunnen worden opgeslagen in de surrogaat. Enkele mogelijke toepassingen zijn: de velden rechtstreeks toewijzen, bewerkingen uitvoeren op de gegevens die moeten worden opgeslagen in de surrogated velden of het opslaan van de XML van het oorspronkelijke type in het ge surrogeerde veld.

De targetType parameter verwijst naar het gedeclareerde type van het lid. Deze parameter is het vervangende type dat door de GetDataContractType methode wordt geretourneerd. De serializer dwingt niet af dat het geretourneerde object kan worden toegewezen aan dit type. De obj parameter is het object dat moet worden geserialiseerd en wordt zo nodig geconverteerd naar het surrogaat. Deze methode moet het invoerobject retourneren als het surrogated het object niet verwerkt. Anders wordt het nieuwe surrogaatobject geretourneerd. De surrogaat wordt niet aangeroepen als het object null is. Er kunnen binnen deze methode talloze surrogaattoewijzingen voor verschillende exemplaren worden gedefinieerd.

Wanneer u een DataContractSerializerobject maakt, kunt u deze instrueren om objectverwijzingen te behouden. (Zie voor meer informatie Serialisatie en deserialisatie.) Dit wordt gedaan door de parameter in de preserveObjectReferences constructor in te stellen op true. In dat geval wordt de surrogaat slechts één keer voor een object aangeroepen, omdat alle volgende serialisaties de verwijzing naar de stream schrijven. Als preserveObjectReferences dit is ingesteld falseop , wordt de surrogaat aangeroepen telkens wanneer een exemplaar wordt aangetroffen.

Als het type van het geserialiseerde exemplaar afwijkt van het gedeclareerde type, wordt typegegevens bijvoorbeeld naar de stroom geschreven, xsi:type zodat het exemplaar aan het andere uiteinde kan worden gedeserialiseerd. Dit proces treedt op of het object al dan niet wordt vervangen.

In het bovenstaande voorbeeld worden de gegevens van het Inventory exemplaar geconverteerd naar die van InventorySurrogated. Het controleert het type van het object en voert de benodigde manipulaties uit om te converteren naar het ge surrogeerde type. In dit geval worden de velden van de Inventory klasse rechtstreeks gekopieerd naar de InventorySurrogated klassevelden.

Methode GetDeserializedObject

Met GetDeserializedObject de methode wordt het exemplaar van het surrogated type geconverteerd naar het oorspronkelijke typeexemplaren. Het is vereist voor deserialisatie.

De volgende taak is het definiëren van de manier waarop de fysieke gegevens worden toegewezen van het surrogaatexemplaren aan het origineel. Voorbeeld:

public object GetDeserializedObject(object obj, Type targetType)
{
    Console.WriteLine("GetDeserializedObject");
    if (obj is InventorySurrogated)
    {
        Inventory invent = new Inventory();
        invent.pens = ((InventorySurrogated)obj).pens;
        invent.pencils = ((InventorySurrogated)obj).numpencils;
        invent.paper = ((InventorySurrogated)obj).numpaper;
        return invent;
    }
    return obj;
}

Deze methode wordt alleen aangeroepen tijdens de deserialisatie van een object. Het biedt omgekeerde gegevenstoewijzing voor de deserialisatie van het surrogaattype terug naar het oorspronkelijke type. Net als bij de GetObjectToSerialize methode kunnen sommige mogelijke toepassingen worden gebruikt om veldgegevens rechtstreeks uit te wisselen, bewerkingen uit te voeren op de gegevens en XML-gegevens op te slaan. Bij het deserialiseren kunt u mogelijk niet altijd de exacte gegevenswaarden ophalen uit het origineel vanwege manipulaties in de gegevensconversie.

De targetType parameter verwijst naar het gedeclareerde type van het lid. Deze parameter is het vervangende type dat door de GetDataContractType methode wordt geretourneerd. De obj parameter verwijst naar het object dat is gedeserialiseerd. Het object kan worden teruggezet naar het oorspronkelijke type als het wordt vervangen. Met deze methode wordt het invoerobject geretourneerd als het surrogaat het object niet verwerkt. Anders wordt het gedeserialiseerde object geretourneerd zodra de conversie is voltooid. Als er verschillende surrogaattypen bestaan, kunt u gegevensconversie van surrogaat naar primair type opgeven door elk type en de bijbehorende conversie aan te geven.

Wanneer u een object retourneert, worden de interne objecttabellen bijgewerkt met het object dat door deze surrogaat wordt geretourneerd. Alle volgende verwijzingen naar een exemplaar verkrijgen het vervangende exemplaar uit de objecttabellen.

In het vorige voorbeeld worden objecten van het type InventorySurrogated weer geconverteerd naar het oorspronkelijke type Inventory. In dit geval worden gegevens rechtstreeks teruggestuurd naar InventorySurrogated de bijbehorende velden in Inventory. Omdat er geen gegevensmanipulaties zijn, bevatten de ledenvelden dezelfde waarden als vóór de serialisatie.

Methode GetCustomDataToExport

Bij het exporteren van een schema is de GetCustomDataToExport methode optioneel. Het wordt gebruikt om extra gegevens of hints in het geëxporteerde schema in te voegen. Aanvullende gegevens kunnen worden ingevoegd op lidniveau of typeniveau. Voorbeeld:

public object GetCustomDataToExport(System.Reflection.MemberInfo memberInfo, Type dataContractType)
{
    Console.WriteLine("GetCustomDataToExport(Member)");
    System.Reflection.FieldInfo fieldInfo = (System.Reflection.FieldInfo)memberInfo;
    if (fieldInfo.IsPublic)
    {
        return "public";
    }
    else
    {
        return "private";
    }
}

Met deze methode (met twee overbelastingen) kan extra informatie worden opgenomen in de metagegevens op lid- of typeniveau. Het is mogelijk om hints op te nemen over of een lid openbaar of privé is en opmerkingen die tijdens de export en het importeren van het schema behouden blijven. Dergelijke informatie zou verloren gaan zonder deze methode. Deze methode veroorzaakt geen invoeging of verwijdering van leden of typen, maar voegt op een van deze niveaus aanvullende gegevens toe aan de schema's.

De methode is overbelast en kan een Type (clrtype parameter) of MemberInfo (memberInfo parameter) gebruiken. De tweede parameter is altijd een Type (dataContractType parameter). Deze methode wordt aangeroepen voor elk lid en type van het surrogated dataContractType type.

Een van deze overbelastingen moet ofwel null een serializeerbaar object retourneren. Een niet-null-object wordt geserialiseerd als aantekening in het geëxporteerde schema. Voor de Type overbelasting wordt elk type dat naar het schema wordt geëxporteerd, naar deze methode verzonden in de eerste parameter, samen met het vervangende type als de dataContractType parameter. Voor de MemberInfo overbelasting verzendt elk lid dat naar het schema wordt geëxporteerd de informatie als de memberInfo parameter met het surrogated type in de tweede parameter.

Methode GetCustomDataToExport (type, type)

De IDataContractSurrogate.GetCustomDataToExport(Type, Type) methode wordt aangeroepen tijdens het exporteren van schema's voor elke typedefinitie. De methode voegt informatie toe aan de typen in het schema bij het exporteren. Elk type dat is gedefinieerd, wordt naar deze methode verzonden om te bepalen of er aanvullende gegevens moeten worden opgenomen in het schema.

Methode GetCustomDataToExport (MemberInfo, Type)

De IDataContractSurrogate.GetCustomDataToExport(MemberInfo, Type) naam wordt aangeroepen tijdens het exporteren voor elk lid in de typen die worden geëxporteerd. Met deze functie kunt u eventuele opmerkingen aanpassen voor de leden die bij het exporteren in het schema worden opgenomen. De informatie voor elk lid in de klasse wordt naar deze methode verzonden om te controleren of er extra gegevens in het schema moeten worden toegevoegd.

In het bovenstaande voorbeeld wordt gezocht naar elk dataContractType lid van het surrogaat. Vervolgens wordt de juiste toegangsaanpassing voor elk veld geretourneerd. Zonder deze aanpassing is de standaardwaarde voor toegangsaanpassingen openbaar. Daarom worden alle leden gedefinieerd als openbaar in de code die wordt gegenereerd met behulp van het geëxporteerde schema, ongeacht wat hun werkelijke toegangsbeperkingen zijn. Wanneer deze implementatie niet wordt gebruikt, is het lid numpens openbaar in het geëxporteerde schema, ook al is het in het surrogaat gedefinieerd als privé. Door deze methode te gebruiken, kan in het geëxporteerde schema de toegangsaanpassing worden gegenereerd als privé.

Methode GetReferencedTypeOnImport

Met deze methode wordt het Type surrogaat toegewezen aan het oorspronkelijke type. Deze methode is optioneel voor het importeren van schema's.

Wanneer u een surrogaat maakt waarmee een schema wordt geïmporteerd en code voor het schema wordt gegenereerd, is de volgende taak het type van een surrogaatexemplaren op het oorspronkelijke type te definiëren.

Als de gegenereerde code moet verwijzen naar een bestaand gebruikerstype, wordt dit gedaan door de GetReferencedTypeOnImport methode te implementeren.

Bij het importeren van een schema wordt deze methode aangeroepen voor elke typedeclaratie om het ge surrogeerde gegevenscontract toe te wijzen aan een type. De tekenreeksparameters typeName en typeNamespace definiëren de naam en naamruimte van het vervangen type. De retourwaarde wordt GetReferencedTypeOnImport gebruikt om te bepalen of een nieuw type moet worden gegenereerd. Deze methode moet een geldig type of null retourneren. Voor geldige typen wordt het geretourneerde type gebruikt als een type waarnaar wordt verwezen in de gegenereerde code. Als er null wordt geretourneerd, wordt er geen naar een type verwezen en moet er een nieuw type worden gemaakt. Als er meerdere surrogaten bestaan, is het mogelijk om de toewijzing voor elk surrogaattype terug te voeren naar het oorspronkelijke type.

De customData parameter is het object dat oorspronkelijk is geretourneerd van GetCustomDataToExport. Dit customData wordt gebruikt wanneer surrogaatauteurs extra gegevens/hints willen invoegen in de metagegevens die tijdens het importeren moeten worden gebruikt om code te genereren.

Methode ProcessImportedType

Met de ProcessImportedType methode wordt elk type aangepast dat is gemaakt op basis van schemaimport. Deze methode is optioneel.

Bij het importeren van een schema kan met deze methode alle geïmporteerde type- en compilatiegegevens worden aangepast. Voorbeeld:

public System.CodeDom.CodeTypeDeclaration ProcessImportedType(System.CodeDom.CodeTypeDeclaration typeDeclaration, System.CodeDom.CodeCompileUnit compileUnit)
{
    Console.WriteLine("ProcessImportedType");
    foreach (CodeTypeMember member in typeDeclaration.Members)
    {
        object memberCustomData = member.UserData[typeof(IDataContractSurrogate)];
        if (memberCustomData != null
          && memberCustomData is string
          && ((string)memberCustomData == "private"))
        {
            member.Attributes = ((member.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Private);
        }
    }
    return typeDeclaration;
}

Tijdens het importeren wordt deze methode aangeroepen voor elk type dat wordt gegenereerd. Wijzig de opgegeven CodeTypeDeclaration of wijzig de CodeCompileUnit. Dit omvat het wijzigen van de naam, leden, kenmerken en vele andere eigenschappen van de CodeTypeDeclaration. Door de instructies, naamruimten, assembly's en verschillende andere aspecten te wijzigen, kunt u de CodeCompileUnitinstructies, naamruimten, assembly's waarnaar wordt verwezen, wijzigen.

De CodeTypeDeclaration parameter bevat de declaratie van het DOM-type code. Met CodeCompileUnit de parameter kan de code worden gewijzigd. Retourneert null resultaten in de typedeclaratie die wordt verwijderd. Omgekeerd blijven de wijzigingen behouden bij het retourneren van een CodeTypeDeclaration.

Als aangepaste gegevens worden ingevoegd tijdens het exporteren van metagegevens, moeten deze tijdens het importeren aan de gebruiker worden opgegeven, zodat deze kunnen worden gebruikt. Deze aangepaste gegevens kunnen worden gebruikt voor hints voor programmeermodellen of andere opmerkingen. Elk CodeTypeDeclaration exemplaar CodeTypeMember bevat aangepaste gegevens als eigenschap UserData , die naar het IDataContractSurrogate type worden gecast.

In het bovenstaande voorbeeld worden enkele wijzigingen aangebracht in het geïmporteerde schema. De code behoudt privéleden van het oorspronkelijke type met behulp van een surrogaat. De standaardaanpassing voor toegang bij het importeren van een schema is public. Daarom zijn alle leden van het surrogaatschema openbaar, tenzij gewijzigd, zoals in dit voorbeeld. Tijdens het exporteren worden aangepaste gegevens ingevoegd in de metagegevens over welke leden privé zijn. Het voorbeeld zoekt de aangepaste gegevens op, controleert of de toegangsaanpassing privé is en wijzigt vervolgens het juiste lid om privé te zijn door de kenmerken ervan in te stellen. Zonder deze aanpassing wordt het numpens lid gedefinieerd als openbaar in plaats van privé.

Methode GetKnownCustomDataTypes

Met deze methode worden aangepaste gegevenstypen opgehaald die zijn gedefinieerd in het schema. De methode is optioneel voor het importeren van schema's.

De methode wordt aangeroepen aan het begin van het exporteren en importeren van schema's. De methode retourneert de aangepaste gegevenstypen die worden gebruikt in het geëxporteerde of geïmporteerde schema. De methode wordt doorgegeven aan een Collection<T> (de customDataTypes parameter), een verzameling typen. De methode moet extra bekende typen toevoegen aan deze verzameling. De bekende aangepaste gegevenstypen zijn nodig om serialisatie en deserialisatie van aangepaste gegevens mogelijk te maken met behulp van de DataContractSerializer. Zie Bekende typen gegevenscontracten voor meer informatie.

Een surrogaat implementeren

Als u de datacontract surrogaat binnen WCF wilt gebruiken, moet u een paar speciale procedures volgen.

Een surrogaat gebruiken voor serialisatie en deserialisatie

Gebruik de DataContractSerializer opdracht om serialisatie en deserialisatie van gegevens uit te voeren met de surrogaat. De DataContractSerializer wordt gemaakt door de DataContractSerializerOperationBehavior. De surrogaat moet ook worden opgegeven.

Serialisatie en deserialisatie implementeren
  1. Maak een exemplaar van de ServiceHost service. Zie Basic WCF Programming voor volledige instructies.

  2. Zoek de opgegeven servicehost voor elke ServiceEndpoint opgegeven servicehost OperationDescription.

  3. Doorzoek het werkingsgedrag om te bepalen of er een exemplaar van de DataContractSerializerOperationBehavior gevonden is.

  4. Als er een DataContractSerializerOperationBehavior wordt gevonden, stelt u DataContractSurrogate de eigenschap ervan in op een nieuw exemplaar van de surrogaat. Als er geen DataContractSerializerOperationBehavior wordt gevonden, maakt u een nieuw exemplaar en stelt u het DataContractSurrogate lid van het nieuwe gedrag in op een nieuw exemplaar van de surrogaat.

  5. Voeg ten slotte dit nieuwe gedrag toe aan het huidige werkingsgedrag, zoals wordt weergegeven in het volgende voorbeeld:

    using (ServiceHost serviceHost = new ServiceHost(typeof(InventoryCheck)))
        foreach (ServiceEndpoint ep in serviceHost.Description.Endpoints)
        {
            foreach (OperationDescription op in ep.Contract.Operations)
            {
                DataContractSerializerOperationBehavior dataContractBehavior =
                    op.Behaviors.Find<DataContractSerializerOperationBehavior>()
                    as DataContractSerializerOperationBehavior;
                if (dataContractBehavior != null)
                {
                    dataContractBehavior.DataContractSurrogate = new InventorySurrogated();
                }
                else
                {
                    dataContractBehavior = new DataContractSerializerOperationBehavior(op);
                    dataContractBehavior.DataContractSurrogate = new InventorySurrogated();
                    op.Behaviors.Add(dataContractBehavior);
                }
            }
        }
    

Een surrogaat gebruiken voor het importeren van metagegevens

Bij het importeren van metagegevens zoals WSDL en XSD om code aan de clientzijde te genereren, moet de surrogaat worden toegevoegd aan het onderdeel dat verantwoordelijk is voor het genereren van code van het XSD-schema. XsdDataContractImporter U doet dit door de WsdlImporter gebruikte metagegevens rechtstreeks te wijzigen.

Een surrogaat implementeren voor import van metagegevens
  1. Importeer de metagegevens met behulp van de WsdlImporter klasse.

  2. Gebruik de TryGetValue methode om te controleren of er een XsdDataContractImporter is gedefinieerd.

  3. Als de TryGetValue methode wordt geretourneerd false, maakt u een nieuwe XsdDataContractImporter en stelt u Options de eigenschap ervan in op een nieuw exemplaar van de ImportOptions klasse. Gebruik anders de importfunctie die wordt geretourneerd door de out parameter van de TryGetValue methode.

  4. Als de XsdDataContractImporter eigenschap niet ImportOptions is gedefinieerd, stelt u de eigenschap in op een nieuw exemplaar van de ImportOptions klasse.

  5. Stel de DataContractSurrogate eigenschap van de eigenschap van de ImportOptions eigenschap XsdDataContractImporter in op een nieuw exemplaar van de surrogaat.

  6. Voeg de XsdDataContractImporter verzameling toe die wordt geretourneerd door de State eigenschap van de WsdlImporter (overgenomen van de MetadataExporter klasse).)

  7. Gebruik de ImportAllContracts methode van de WsdlImporter methode om alle gegevenscontracten in het schema te importeren. Tijdens de laatste stap wordt code gegenereerd op basis van de schema's die worden geladen door het aanroepen van de surrogaat.

    MetadataExchangeClient mexClient = new MetadataExchangeClient(metadataAddress);
    mexClient.ResolveMetadataReferences = true;
    MetadataSet metaDocs = mexClient.GetMetadata();
    WsdlImporter importer = new WsdlImporter(metaDocs);
    object dataContractImporter;
    XsdDataContractImporter xsdInventoryImporter;
    if (!importer.State.TryGetValue(typeof(XsdDataContractImporter),
        out dataContractImporter))
        xsdInventoryImporter = new XsdDataContractImporter();
    
    xsdInventoryImporter = (XsdDataContractImporter)dataContractImporter;
    xsdInventoryImporter.Options ??= new ImportOptions();
    xsdInventoryImporter.Options.DataContractSurrogate = new InventorySurrogated();
    importer.State.Add(typeof(XsdDataContractImporter), xsdInventoryImporter);
    
    Collection<ContractDescription> contracts = importer.ImportAllContracts();
    

Een surrogaat gebruiken voor het exporteren van metagegevens

Bij het exporteren van metagegevens uit WCF voor een service moeten standaard zowel WSDL- als XSD-schema worden gegenereerd. De surrogaat moet worden toegevoegd aan het onderdeel dat verantwoordelijk is voor het genereren van XSD-schema voor gegevenscontracttypen, XsdDataContractExporter. Hiervoor gebruikt u een gedrag dat wordt geïmplementeerd IWsdlExportExtension om het WsdlExporterte wijzigen of de gebruikte metagegevens rechtstreeks te wijzigen WsdlExporter .

Een surrogaat gebruiken voor het exporteren van metagegevens
  1. Maak een nieuwe WsdlExporter of gebruik de wsdlExporter parameter die aan de ExportContract methode is doorgegeven.

  2. Gebruik de TryGetValue functie om te controleren of er een XsdDataContractExporter is gedefinieerd.

  3. Als TryGetValue dit falsewordt geretourneerd, maakt u een nieuwe XsdDataContractExporter met de gegenereerde XML-schema's van de WsdlExporteren voegt u deze toe aan de verzameling die wordt geretourneerd door de State eigenschap van de WsdlExporter. Gebruik anders de exporteur die is geretourneerd door de out parameter van de TryGetValue methode.

  4. Als de XsdDataContractExporter eigenschap niet ExportOptions is gedefinieerd, stelt u de Options eigenschap in op een nieuw exemplaar van de ExportOptions klasse.

  5. Stel de DataContractSurrogate eigenschap van de eigenschap van de ExportOptions eigenschap XsdDataContractExporter in op een nieuw exemplaar van de surrogaat. Voor volgende stappen voor het exporteren van metagegevens zijn geen wijzigingen vereist.

    WsdlExporter exporter = new WsdlExporter();
    //or
    //public void ExportContract(WsdlExporter exporter,
    // WsdlContractConversionContext context) { ... }
    object dataContractExporter;
    XsdDataContractExporter xsdInventoryExporter;
    if (!exporter.State.TryGetValue(typeof(XsdDataContractExporter),
        out dataContractExporter))
    {
        xsdInventoryExporter = new XsdDataContractExporter(exporter.GeneratedXmlSchemas);
    }
    else
    {
        xsdInventoryExporter = (XsdDataContractExporter)dataContractExporter;
    }
    
    exporter.State.Add(typeof(XsdDataContractExporter), xsdInventoryExporter);
    
    if (xsdInventoryExporter.Options == null)
        xsdInventoryExporter.Options = new ExportOptions();
    xsdInventoryExporter.Options.DataContractSurrogate = new InventorySurrogated();
    

Zie ook