다음을 통해 공유


DataContractResolver

이 샘플에서는 DataContractResolver 클래스를 사용하여 serialization 및 deserialization 프로세스를 사용자 지정하는 방법을 보여 줍니다. 이 샘플에서는 serialization 및 deserialization 동안 알려진 형식을 동적으로 추가하는 방법을 보여 줍니다.

샘플 세부 정보

다음 코드 예제에서는 다음 형식이 포함된 어셈블리를 보여 줍니다.

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

이 샘플에서는 어셈블리를 반영하고 어셈블리의 각 형식을 추출한 다음 serialize 및 deserialize합니다. DataContractResolver는 다음 예제와 같이 DataContractSerializer 생성자에 연결됩니다.

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

다음 코드 예제에서는 어셈블리의 형식을 serialize하는 방법을 보여 줍니다.

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

다음 코드 예제에서는 어셈블리의 형식을 deserialize하는 방법을 보여 줍니다.

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

DataContractResolverDataContractSerializer 생성자에 연결되면 항상 알려진 형식의 serialization 및 deserialization 논리 대신 데이터 계약 확인자에 정의된 논리가 사용됩니다. 특히 DataContractResolver에는 두 개의 중요한 메서드가 있습니다. TryResolveType 메서드는 serialization 시 임의의 형식을 새 xsi:type 표현에 매핑하는 데 사용되고 TryResolveType 메서드는 deserialization 시 xsi:type을 임의의 형식에 매핑하는 데 사용됩니다. 이 샘플에서 DataContractResolver는 다음 예제와 같이 정의됩니다.

다음 코드 예제는 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);
        }
    }
} 

샘플에 포함된 Types 프로젝트에서는 이 샘플에 사용되는 모든 형식을 포함하는 어셈블리를 생성합니다. 이 프로젝트를 사용하여 serialize할 형식을 추가, 제거 또는 수정합니다.

이 샘플을 사용하려면

  1. Visual Studio 2010에서 DCRSample.sln 솔루션 파일을 엽니다.

  2. F5 키를 눌러 솔루션을 실행합니다.

Dd807504.Important(ko-kr,VS.100).gif 참고:
컴퓨터에 이 샘플이 이미 설치되어 있을 수도 있습니다. 계속하기 전에 다음(기본) 디렉터리를 확인하십시오.

<InstallDrive>:\WF_WCF_Samples

이 디렉터리가 없으면 Windows Communication Foundation (WCF) and Windows Workflow Foundation (WF) Samples for .NET Framework 4로 이동하여 WCF(Windows Communication Foundation) 및 WF 샘플을 모두 다운로드하십시오. 이 샘플은 다음 디렉터리에 있습니다.

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