DataContractResolver 샘플은 클래스를 사용하여 DataContractResolver 직렬화 및 역직렬화 프로세스를 사용자 지정하는 방법을 보여 줍니다. 이 샘플에서는 DataContractResolver를 사용하여 직렬화 및 역직렬화 중에 CLR 형식을 xsi:type 표현과 매핑하는 방법을 보여 줍니다.
샘플 세부 정보
샘플은 다음 CLR 형식을 정의합니다.
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
{
}
}
샘플은 어셈블리를 로드하고, 이러한 각 형식을 추출한 다음, 직렬화하고 역직렬화합니다. 다음 DataContractResolver 예제와 같이 파생 클래스 DataContractResolver 의 DataContractSerializer인스턴스를 생성자에 전달하여 serialization 프로세스에 연결됩니다.
this.serializer = new DataContractSerializer(typeof(Object), null, int.MaxValue, false, true, null, new MyDataContractResolver(assembly));
그런 다음 샘플이 다음 코드 예제에서 보여주듯이 CLR 타입을 직렬화합니다.
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:types를 역직렬화합니다.
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 생성자에 전달되기 때문에, 직렬화 중에 CLR 형식을 동등한 TryResolveType 형식에 매핑하기 위해 xsi:type
가 호출된다. 마찬가지로 역직렬화 중에 ResolveName가 호출되어 xsi:type
를 해당하는 CLR 형식에 매핑합니다. 이 샘플에서는 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할 형식을 추가, 제거 또는 수정할 수 있습니다.
이 샘플을 사용하려면
Visual Studio를 사용하여 DCRSample.sln 솔루션 파일을 엽니다.
솔루션을 실행하려면 F5 키를 누릅니다.