Verwenden eines DatenvertragsresolversUsing a Data Contract Resolver

Mithilfe eines Datenvertragsresolver können Sie bekannte Typen dynamisch konfigurieren.A data contract resolver allows you to configure known types dynamically. Bekannte Typen sind erforderlich, wenn ein Typ serialisiert oder deserialisiert wird, der von einem Datenvertrag nicht erwartet wird.Known types are required when serializing or deserializing a type not expected by a data contract. Weitere Informationen über bekannte Typen finden Sie unter Datenvertragstypen bezeichnet.For more information about known types, see Data Contract Known Types. Bekannte Typen werden in der Regel statisch angegeben.Known types are normally specified statically. Das bedeutet, dass Sie beim Implementieren eines Vorgangs alle möglichen Typen kennen müssen, die der Vorgang erhalten kann.This means you would have to know all the possible types an operation may receive while implementing the operation. In einigen Szenarios trifft dies nicht zu, und es ist wichtig, bekannte Typen dynamisch angeben zu können.There are scenarios in which this is not true and being able to specify known types dynamically is important.

Erstellen eines DatenvertragsresolversCreating a Data Contract Resolver

Das Erstellen eines Datenvertragsresolvers umfasst die Implementierung von zwei Methoden: TryResolveType und ResolveName.Creating a data contract resolver involves implementing two methods, TryResolveType and ResolveName. Diese beiden Methoden implementieren Rückrufe, die jeweils während der Serialisierung und der Deserialisierung verwendet werden.These two methods implement callbacks that are used during serialization and deserialization, respectively. Die TryResolveType-Methode wird während der Serialisierung aufgerufen. Sie verwendet einen Datenvertragstyp und ordnet diesen einem xsi:type-Namen und einem Namespace zu.The TryResolveType method is invoked during serialization and takes a data contract type and maps it to an xsi:type name and namespace. Die ResolveName-Methode wird während der Deserialisierung aufgerufen. Sie verwendet einen xsi:type-Namen und einen Namespace und löst diesen zu einem Datenvertragstyp auf.The ResolveName method is invoked during deserialization and takes an xsi:type name and namespace and resolves it to a data contract type. Beide Methoden verfügen über einen knownTypeResolver-Parameter, der verwendet werden kann, um den standardmäßigen bekannten Typresolver in der Implementierung zu verwenden.Both of these methods have a knownTypeResolver parameter that can be used to use the default known type resolver in your implementation.

Im folgenden Beispiel wird gezeigt, wie Sie einen DataContractResolver implementieren, um die Zuordnung zu und von einem Datenvertragstyp mit dem Namen Customer vorzunehmen, der vom einem Datenvertragstyp Person abgeleitet wurde.The following example shows how to implement a DataContractResolver to map to and from a data contract type named Customer derived from a data contract type 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);  
        }  
    }  
}  

Nachdem Sie einen DataContractResolver definiert haben, können Sie diesen verwenden, indem Sie ihn an den DataContractSerializer-Konstruktor übergeben. Dies ist im folgenden Beispiel dargestellt.Once you have defined a DataContractResolver you can use it by passing it to the DataContractSerializer constructor as shown in the following example.

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

Sie können einen DataContractSerializer in einem Aufruf der Methoden ReadObject oder WriteObject angeben, wie im folgenden Beispiel gezeigt.You can specify a DataContractSerializer in a call to the ReadObject or WriteObject methods, as shown in the following example.

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()));  

Sie können ihn jedoch auch unter DataContractSerializerOperationBehavior festlegen, wie im folgenden Beispiel gezeigt.Or you can set it on the DataContractSerializerOperationBehavior as shown in the following example.

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();  

Sie können einen Datenvertragsresolver deklarativ angeben, indem Sie ein Attribut implementieren, das auf einen Dienst angewendet werden kann.You can declaratively specify a data contract resolver by implementing an attribute that can be applied to a service. Weitere Informationen finden Sie unter der KnownAssemblyAttribute Beispiel.For more information, see the KnownAssemblyAttribute sample. Diesem Beispiel wird ein Attribut mit dem Namen "KnownAssembly" implementiert, das Verhalten des Diensts einen benutzerdefinierten datenvertragsresolver hinzufügt.This sample implements an attribute called "KnownAssembly" that adds a custom data contract resolver to the service’s behavior.

Siehe auchSee Also

Bekannte Typen in DatenverträgenData Contract Known Types
DataContractSerializer-BeispielDataContractSerializer Sample
KnownAssemblyAttributeKnownAssemblyAttribute