Bagikan melalui


DataContractResolver

Sampel DataContractResolver menunjukkan bagaimana proses serialisasi dan deserialisasi dapat disesuaikan menggunakan kelas DataContractResolver. 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 assembly, mengekstrak setiap jenis ini, kemudian menserialisasikan serta mendeserialisasikannya. DataContractResolver disambungkan ke proses serialisasi dengan meneruskan instans kelas turunan-DataContractResolver ke konstruktor DataContractSerializer, seperti yang ditampilkan pada contoh berikut.

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

Sampel kemudian menserialisasi jenis CLR seperti yang ditunjukkan pada 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:types seperti yang ditampilkan 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 DataContractResolver kustom diteruskan ke konstruktor DataContractSerializer, TryResolveType dipanggil selama serialisasi untuk memetakan jenis CLR ke xsi:type yang setara. Sama halnya ResolveName yang dipanggil selama deserialisasi untuk memetakan xsi:type ke jenis CLR yang setara. Pada sampel ini, DataContractResolver ditentukan seperti yang ditampilkan pada 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 Jenis menghasilkan assembly dengan semua jenis yang digunakan dalam sampel ini. Gunakan proyek ini untuk menambahkan, menghapus, atau memodifikasi jenis yang akan diserialisasikan.

Untuk menggunakan sampel ini

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

  2. Untuk menjalankan solusi, tekan F5.

Lihat juga