Bagikan melalui


DataContractResolver

Sampel DataContractResolver menunjukkan bagaimana proses serialisasi dan deserialisasi dapat disesuaikan dengan menggunakan DataContractResolver kelas . Sampel ini menunjukkan cara menggunakan DataContractResolver untuk memetakan jenis CLR ke dan dari representasi xsi:type selama serialisasi dan deserialisasi.

Detail Sampel

Sampel menentukan jenis CLR berikut.

using System;
using System.Runtime.Serialization;

namespace Types
{
    [DataContract]
    public class Customer
    {
        [DataMember]
        public string Name { get; set; }
    }

    [DataContract]
    public class VIPCustomer : Customer
    {
        [DataMember]
        public string VipInfo { get; set; }
    }

    [DataContract]
    public class RegularCustomer : Customer
    {
    }

    [DataContract]
    public class PreferredVIPCustomer : VIPCustomer
    {
    }
}

Sampel memuat rakitan, mengekstrak masing-masing jenis ini, lalu menserialisasikan dan mendeserialisasinya. DataContractResolver diintegrasikan ke dalam proses serialisasi dengan meneruskan instans kelas turunan DataContractResolver ke konstruktor DataContractSerializer, seperti yang ditunjukkan dalam contoh berikut.

this.serializer = new DataContractSerializer(typeof(Object), null, int.MaxValue, false, true, null, new MyDataContractResolver(assembly));

Sampel kemudian menserialisasikan jenis CLR seperti yang ditunjukkan dalam contoh kode berikut.

Assembly assembly = Assembly.Load(new AssemblyName("Types"));

public void serialize(Type type)
{
    Object instance = Activator.CreateInstance(type);

    Console.WriteLine("----------------------------------------");
    Console.WriteLine();
    Console.WriteLine("Serializing type: {0}", type.Name);
    Console.WriteLine();
    this.buffer = new StringBuilder();
    using (XmlWriter xmlWriter = XmlWriter.Create(this.buffer))
    {
        try
        {
            this.serializer.WriteObject(xmlWriter, instance);
        }
        catch (SerializationException error)
        {
            Console.WriteLine(error.ToString());
        }
    }
    Console.WriteLine(this.buffer.ToString());
}

Sampel kemudian mendeserialisasi xsi:type seperti yang ditunjukkan dalam contoh kode berikut.

public void deserialize(Type type)
{
    Console.WriteLine();
    Console.WriteLine("Deserializing type: {0}", type.Name);
    Console.WriteLine();
    using (XmlReader xmlReader = XmlReader.Create(new StringReader(this.buffer.ToString())))
    {
        Object obj = this.serializer.ReadObject(xmlReader);
    }
}

Karena kustom DataContractResolver diteruskan ke konstruktor DataContractSerializer, TryResolveType dipanggil selama serialisasi untuk memetakan tipe CLR ke xsi:type yang setara. Demikian pula, ResolveName dipanggil selama deserialisasi untuk memetakan xsi:type ke tipe CLR yang setara. Dalam sampel ini, DataContractResolver didefinisikan seperti yang ditunjukkan dalam contoh berikut.

Contoh kode berikut adalah kelas yang berasal dari DataContractResolver.

class MyDataContractResolver : DataContractResolver
{
    private Dictionary<string, XmlDictionaryString> dictionary = new Dictionary<string, XmlDictionaryString>();
    Assembly assembly;

    public MyDataContractResolver(Assembly assembly)
    {
        this.assembly = assembly;
    }

    // Used at deserialization
    // Allows users to map xsi:type name to any Type
    public override Type ResolveName(string typeName, string typeNamespace, DataContractResolver knownTypeResolver)
    {
        XmlDictionaryString tName;
        XmlDictionaryString tNamespace;
        if (dictionary.TryGetValue(typeName, out tName) && dictionary.TryGetValue(typeNamespace, out tNamespace))
        {
            return this.assembly.GetType(tNamespace.Value + "." + tName.Value);
        }
        else
        {
            return null;
        }
    }

    // Used at serialization
    // Maps any Type to a new xsi:type representation
    public override void ResolveType(Type dataContractType, DataContractResolver knownTypeResolver, out XmlDictionaryString typeName, out XmlDictionaryString typeNamespace)
    {
        string name = dataContractType.Name;
        string namesp = dataContractType.Namespace;
        typeName = new XmlDictionaryString(XmlDictionary.Empty, name, 0);
        typeNamespace = new XmlDictionaryString(XmlDictionary.Empty, namesp, 0);
        if (!dictionary.ContainsKey(dataContractType.Name))
        {
            dictionary.Add(name, typeName);
        }
        if (!dictionary.ContainsKey(dataContractType.Namespace))
        {
            dictionary.Add(namesp, typeNamespace);
        }
    }
}

Sebagai bagian dari sampel, proyek Tipe menghasilkan assembly dengan semua tipe yang digunakan dalam sampel ini. Gunakan proyek ini untuk menambahkan, menghapus, atau mengubah jenis yang akan diserialisasikan.

Untuk menggunakan sampel ini

  1. Menggunakan Visual Studio, buka file solusi DCRSample.sln.

  2. Untuk menjalankan solusi, tekan F5.

Lihat juga