DataContractResolverDataContractResolver

此範例示範如何使用 DataContractResolver 類別來自訂序列化和還原序列化程序。This sample demonstrates how the serialization and deserialization processes can be customized by using the DataContractResolver class. 此範例會示範如何使用 DataContractResolver,在序列化和還原序列化期間來回對應 CLR 型別與 xsi:type 表示。This sample shows how to use a DataContractResolver to map CLR types to and from an xsi:type representation during serialization and deserialization.

範例詳細資料Sample Details

此範例會定義下列 CLR 型別。The sample defines the following CLR types.

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
    {
    }
}

此範例會載入組件、擷取其中每個型別,然後序列化和還原序列化這些型別。The sample loads the assembly, extracts each of these types, and then serializes and deserializes them. 系統會將 DataContractResolver 衍生類別的執行個體傳遞給 DataContractResolver 建構函式,藉以將 DataContractSerializer 插入序列化程序中,如下列範例所示。The DataContractResolver is plugged into the serialization process by passing an instance of the DataContractResolver-derived class to the DataContractSerializer constructor, as shown in the following example.

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

然後,此範例會序列化這些 CLR 型別,如下列程式碼範例所示。The sample then serializes the CLR types as shown in the following code example.

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

然後,此範例會還原序列化這些 xsi:type,如下列程式碼範例所示。The sample then deserializes the xsi:types as shown in the following code example.

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

因為自訂 DataContractResolver 已傳入 DataContractSerializer 建構函式,所以系統會在序列化期間呼叫 TryResolveType,以便將 CLR 型別對應至對等的 xsi:typeSince the custom DataContractResolver is passed in to the DataContractSerializer constructor, the TryResolveType is called during serialization to map a CLR type to an equivalent xsi:type. 同樣地,系統會在還原序列化期間呼叫 ResolveName,以便將 xsi:type 對應至對等的 CLR 型別。Similarly the ResolveName is called during deserialization to map the xsi:type to an equivalent CLR type. 在此範例中,DataContractResolver 定義的方式如下列範例所示。In this sample, the DataContractResolver is defined as shown in the following example.

下列程式碼範例是從 DataContractResolver 衍生的類別。The following code example is a class deriving from 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);
        }
    }
}

在此範例中,類型專案會產生包含此範例中使用之所有類型的組件。As part of the sample, the Types project generates the assembly with all the types that are used in this sample. 使用此專案加入、移除或修改即將序列化的類型。Use this project to add, remove or modify the types that will be serialized.

若要使用這個範例To use this sample

  1. 使用 Visual Studio 2012,請開啟 DCRSample.sln 方案檔案。Using Visual Studio 2012, open the DCRSample.sln solution file.

  2. 若要執行方案,請按 F5To run the solution, press F5

重要

這些範例可能已安裝在您的電腦上。The samples may already be installed on your machine. 請先檢查下列 (預設) 目錄,然後再繼續。Check for the following (default) directory before continuing.

<InstallDrive>:\WF_WCF_Samples

如果此目錄不存在,請移至Windows Communication Foundation (WCF) 和.NET Framework 4 的 Windows Workflow Foundation (WF) 範例以下載所有 Windows Communication Foundation (WCF) 和WFWF範例。If this directory does not exist, go to Windows Communication Foundation (WCF) and Windows Workflow Foundation (WF) Samples for .NET Framework 4 to download all Windows Communication Foundation (WCF) and WFWF samples. 此範例位於下列目錄。This sample is located in the following directory.

<InstallDrive>:\WF_WCF_Samples\WCF\Basic\Contract\Data\DataContractResolver

另請參閱See also