此示例演示如何使用 DataContractResolver 类来自定义序列化和反序列化过程。此示例演示如何在序列化和反序列化过程中动态添加已知类型。
示例详细信息
下面的代码示例演示具有以下类型的程序集。
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 将插入到 DataContractSerializer 构造函数中,如下面的示例所示。
this.serializer = new DataContractSerializer(typeof(Object), null, int.MaxValue, false, true, null, new MyDataContractResolver(assembly));
以下代码示例演示如何序列化该程序集中的类型。
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());
}
以下代码示例演示如何反序列化该程序集中的类型。
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 构造函数中,因此始终使用数据协定解析程序中定义的逻辑,而不是使用已知类型序列化和反序列化逻辑。特别是,在 DataContractResolver 中有两个重要方法。序列化时使用 TryResolveType 方法将任何类型映射到新的 xsi:type 表示形式,反序列化时使用 TryResolveType 方法将 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 项目将生成具有此示例中所使用的全部类型的程序集。使用此项目可添加、移除或修改将要序列化的所有类型。
使用此示例
使用 Visual Studio 2010 打开 DCRSample.sln 解决方案文件。
若要运行解决方案,请按 F5。
![]() |
---|
您的计算机上可能已安装这些示例。在继续操作之前,请先检查以下(默认)目录:
<安装驱动器>:\WF_WCF_Samples
如果此目录不存在,请访问针对 .NET Framework 4 的 Windows Communication Foundation (WCF) 和 Windows Workflow Foundation (WF) 示例(可能为英文网页),下载所有 Windows Communication Foundation (WCF) 和 WF 示例。此示例位于以下目录。
<安装驱动器>:\WF_WCF_Samples\WCF\Basic\Contract\Data\DataContractResolver
|