Delen via


Een gegevenscontract resolver gebruiken

Met een gegevenscontractomzetting kunt u bekende typen dynamisch configureren. Bekende typen zijn vereist bij het serialiseren of deserialiseren van een type dat niet wordt verwacht door een gegevenscontract. Zie Bekende typen gegevenscontract voor meer informatie over bekende typen. Bekende typen worden normaal gesproken statisch opgegeven. Dit betekent dat u alle mogelijke typen moet weten die een bewerking kan ontvangen tijdens het implementeren van de bewerking. Er zijn scenario's waarin dit niet waar is en het dynamisch kunnen opgeven van bekende typen belangrijk is.

Een gegevenscontract resolver maken

Het maken van een gegevenscontract-resolver omvat het implementeren van twee methoden en TryResolveTypeResolveName. Met deze twee methoden worden callbacks geïmplementeerd die worden gebruikt tijdens de serialisatie en deserialisatie. De TryResolveType methode wordt aangeroepen tijdens de serialisatie en neemt een gegevenscontracttype op en wijst deze toe aan een xsi:type naam en naamruimte. De ResolveName methode wordt aangeroepen tijdens deserialisatie en neemt een xsi:type naam en naamruimte en zet deze om in een gegevenscontracttype. Beide methoden hebben een knownTypeResolver parameter die kan worden gebruikt voor het gebruik van de standaard bekende type resolver in uw implementatie.

In het volgende voorbeeld ziet u hoe u een DataContractResolver gegevenscontracttype implementeert dat wordt toegewezen aan en van een gegevenscontracttype dat Customer is afgeleid van een gegevenscontracttype Person.

public class MyCustomerResolver : DataContractResolver  
{  
    public override bool TryResolveType(Type dataContractType, Type declaredType, DataContractResolver knownTypeResolver, out XmlDictionaryString typeName, out XmlDictionaryString typeNamespace)  
    {  
        if (dataContractType == typeof(Customer))  
        {  
            XmlDictionary dictionary = new XmlDictionary();  
            typeName = dictionary.Add("SomeCustomer");  
            typeNamespace = dictionary.Add("http://tempuri.com");  
            return true;  
        }  
        else  
        {  
            return knownTypeResolver.TryResolveType(dataContractType, declaredType, null, out typeName, out typeNamespace);  
        }  
    }  
  
    public override Type ResolveName(string typeName, string typeNamespace, DataContractResolver knownTypeResolver)  
    {  
        if (typeName == "SomeCustomer" && typeNamespace == "http://tempuri.com")  
        {  
            return typeof(Customer);  
        }  
        else  
        {  
            return knownTypeResolver.ResolveName(typeName, typeNamespace, null);  
        }  
    }  
}  

Zodra u een DataContractResolver app hebt gedefinieerd, kunt u deze gebruiken door deze door te geven aan de DataContractSerializer constructor, zoals wordt weergegeven in het volgende voorbeeld.

XmlObjectSerializer serializer = new DataContractSerializer(typeof(Customer), null, Int32.MaxValue, false, false, null, new MyCustomerResolver());  

U kunt een DataContractResolver aanroep naar de DataContractSerializer.ReadObject of DataContractSerializer.WriteObject methoden opgeven, zoals wordt weergegeven in het volgende voorbeeld.

MemoryStream ms = new MemoryStream();  
DataContractSerializer serializer = new DataContractSerializer(typeof(Customer));  
XmlDictionaryWriter writer = XmlDictionaryWriter.CreateDictionaryWriter(XmlWriter.Create(ms));  
serializer.WriteObject(writer, new Customer(), new MyCustomerResolver());  
writer.Flush();  
ms.Position = 0;  
Console.WriteLine(((Customer)serializer.ReadObject(XmlDictionaryReader.CreateDictionaryReader(XmlReader.Create(ms)), false, new MyCustomerResolver()));  

U kunt deze ook instellen op de DataContractSerializerOperationBehavior zoals wordt weergegeven in het volgende voorbeeld.

ServiceHost host = new ServiceHost(typeof(MyService));  
  
ContractDescription cd = host.Description.Endpoints[0].Contract;  
OperationDescription myOperationDescription = cd.Operations.Find("Echo");  
  
DataContractSerializerOperationBehavior serializerBehavior = myOperationDescription.Behaviors.Find<DataContractSerializerOperationBehavior>();  
if (serializerBehavior == null)  
{  
    serializerBehavior = new DataContractSerializerOperationBehavior(myOperationDescription);  
    myOperationDescription.Behaviors.Add(serializerBehavior);  
}  
  
SerializerBehavior.DataContractResolver = new MyCustomerResolver();  

U kunt declaratief een gegevenscontract resolver opgeven door een kenmerk te implementeren dat kan worden toegepast op een service. Zie het voorbeeld KnownAssemblyAttribute voor meer informatie. In dit voorbeeld wordt een kenmerk met de naam KnownAssembly geïmplementeerd waarmee een aangepaste gegevenscontract-resolver wordt toegevoegd aan het gedrag van de service.

Zie ook