Menggunakan Penyelesai Kontrak Data

Resolver kontrak data memungkinkan Anda mengonfigurasi jenis yang diketahui secara dinamis. Tipe yang dikenal diperlukan saat menserialisasikan atau mendeserialisasi tipe yang tidak diharapkan oleh kontrak data. Untuk informasi selengkapnya tentang jenis yang diketahui, lihat Jenis Kontrak Data yang Diketahui. Jenis yang diketahui biasanya ditentukan secara statis. Ini berarti Anda harus mengetahui semua jenis yang mungkin diterima oleh suatu operasi untuk melaksanakan operasi tersebut. Ada skenario di mana ini tidak benar dan dapat menentukan jenis yang diketahui secara dinamis penting.

Membuat Pemecah Kontrak Data

Membuat resolver kontrak data melibatkan penerapan dua metode, TryResolveType dan ResolveName. Kedua metode ini menerapkan panggilan balik yang digunakan selama serialisasi dan deserialisasi, masing-masing. Metode TryResolveType ini dipanggil selama serialisasi dan mengambil jenis kontrak data dan memetakannya ke xsi:type nama dan namespace. Metode ResolveName ini dipanggil selama deserialisasi dan mengambil xsi:type nama dan namespace dan menyelesaikannya ke jenis kontrak data. Kedua metode ini memiliki knownTypeResolver parameter yang dapat digunakan untuk menggunakan pemecah masalah jenis default yang diketahui dalam implementasi Anda.

Contoh berikut menunjukkan cara menerapkan DataContractResolver untuk memetakan ke dan dari jenis kontrak data bernama Customer yang diturunkan dari jenis kontrak data 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);
        }
    }
}

Setelah Anda menentukan sebuah DataContractResolver, Anda dapat menggunakannya dengan meneruskannya ke konstruktor DataContractSerializer seperti yang ditunjukkan dalam contoh berikut.

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

Anda dapat menentukan DataContractResolver dalam panggilan ke metode DataContractSerializer.ReadObject atau DataContractSerializer.WriteObject, seperti yang ditunjukkan dalam contoh berikut.

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

Atau Anda dapat mengaturnya pada DataContractSerializerOperationBehavior seperti yang ditunjukkan dalam contoh berikut.

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

Anda dapat secara deklaratif menentukan penyelesai kontrak data dengan menerapkan atribut yang dapat diterapkan ke layanan. Untuk informasi selengkapnya, lihat sampel KnownAssemblyAttribute . Sampel ini menerapkan atribut yang disebut "KnownAssembly" yang menambahkan pemecah masalah kontrak data kustom ke perilaku layanan.

Lihat juga