DataContractResolver
In diesem Beispiel wird veranschaulicht, wie die Serialisierungs- und Deserialisierungsprozesse mit der DataContractResolver-Klasse angepasst werden können. In diesem Beispiel wird gezeigt, wie bekannte Typen während der Serialisierung und Deserialisierung dynamisch hinzugefügt werden.
Beispieldetails
Im folgenden Codebeispiel wird eine Assembly mit den folgenden Typen veranschaulicht.
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
{
}
}
Die Assembly wird im Beispiel wiedergegeben, wobei jeder dieser Typen extrahiert und dann serialisiert und deserialisiert wird. Der DataContractResolver wird in den im folgenden Beispiel gezeigten DataContractSerializer-Konstruktor integriert.
this.serializer = new DataContractSerializer(typeof(Object), null, int.MaxValue, false, true, null, new MyDataContractResolver(assembly));
Im folgenden Codebeispiel wird veranschaulicht, wie die Typen in der Assembly serialisiert werden.
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());
}
Im folgenden Codebeispiel wird veranschaulicht, wie die Typen in der Assembly deserialisiert werden.
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);
}
}
Da ein DataContractResolver in den DataContractSerializer-Konstruktor integriert ist, wird immer die im Datenvertragresolver definierte Logik statt der bekannten Typserialisierungs und -deserialisierungslogik verwendet. Der DataContractResolver umfasst vor allem zwei wichtige Methoden. Die TryResolveType-Methode wird bei der Serialisierung zum Zuordnen der Typen zu einer neuen xsi:type-Darstellung und die TryResolveType-Methode bei der Deserialisierung zum Zuordnen von xsi:type zu einem beliebigen Typ verwendet. In diesem Beispiel ist der DataContractResolver wie im folgenden Beispiel definiert.
Das folgende Codebeispiel ist eine vom DataContractResolver abgeleitete Klasse.
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);
}
}
}
Als Teil des Beispiels generiert das Typenprojekt die Assembly mit allen Typen, die in diesem Beispiel verwendet werden. Verwenden Sie dieses Projekt, um die zu serialisierenden Typen hinzuzufügen, zu entfernen oder zu ändern.
So verwenden Sie dieses Beispiel
Öffnen Sie mit Visual Studio 2010 die Projektmappendatei DCRSample.sln.
Drücken Sie F5, um die Projektmappe auszuführen.
Hinweis: |
---|
Die Beispiele sind möglicherweise bereits auf dem Computer installiert. Überprüfen Sie das folgende (standardmäßige) Verzeichnis, bevor Sie fortfahren.
<Installationslaufwerk>:\WF_WCF_Samples
Wenn dieses Verzeichnis nicht vorhanden ist, rufen Sie Windows Communication Foundation (WCF) and Windows Workflow Foundation (WF) Samples for .NET Framework 4 auf, um alle Windows Communication Foundation (WCF)- und WF-Beispiele herunterzuladen. Dieses Beispiel befindet sich im folgenden Verzeichnis.
<Installationslaufwerk>:\WF_WCF_Samples\WCF\Basic\Contract\Data\DataContractResolver
|