Delen via


DataContractResolver

Het DataContractResolver-voorbeeld laat zien hoe de serialisatie- en deserialisatieprocessen kunnen worden aangepast met behulp van de DataContractResolver klasse. In dit voorbeeld ziet u hoe u een DataContractResolver gebruikt om CLR-typen toe te wijzen aan en van een xsi:type-weergave tijdens serialisatie en deserialisatie.

Voorbeelddetails

In het voorbeeld worden de volgende CLR-typen gedefinieerd.

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

Het voorbeeld laadt de assembly, extraheert elk van deze typen en serialiseert en ontserialiseerd ze. De DataContractResolver is aangesloten op het serialisatieproces door een exemplaar van de DataContractResolver-afgeleide klasse door te geven aan de DataContractSerializer constructor, zoals wordt weergegeven in het volgende voorbeeld.

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

Het voorbeeld serialiseert vervolgens de CLR-typen, zoals wordt weergegeven in het volgende codevoorbeeld.

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

In het voorbeeld worden vervolgens de xsi:types gedeserialiseerd, zoals wordt weergegeven in het volgende codevoorbeeld.

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

Omdat de aangepaste DataContractResolver code wordt doorgegeven aan de DataContractSerializer constructor, wordt de TryResolveType aangeroepen tijdens de serialisatie om een CLR-type toe te wijzen aan een equivalent xsi:type. Op dezelfde manier wordt de ResolveName aangeroepen tijdens deserialisatie om het xsi:type toe te wijzen aan een equivalent CLR-type. In dit voorbeeld wordt de DataContractResolver definitie gedefinieerd zoals wordt weergegeven in het volgende voorbeeld.

Het volgende codevoorbeeld is een klasse die is afgeleid van 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);
        }
    }
}

Als onderdeel van het voorbeeld genereert het project Typen de assembly met alle typen die in dit voorbeeld worden gebruikt. Gebruik dit project om de typen toe te voegen, te verwijderen of te wijzigen die worden geserialiseerd.

Dit voorbeeld gebruiken

  1. Open met Visual Studio het DCRSample.sln-oplossingsbestand.

  2. Druk op F5 om de oplossing uit te voeren.

Zie ook