Dela via


DataContractResolver

Exemplet DataContractResolver visar hur serialiserings- och deserialiseringsprocesserna kan anpassas med hjälp DataContractResolver av klassen. Det här exemplet visar hur du använder en DataContractResolver för att mappa CLR-typer till och från en xsi:type-representation under serialisering och deserialisering.

Exempelinformation

Exemplet definierar följande CLR-typer.

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

Exemplet läser in sammansättningen, extraherar var och en av dessa typer och serialiserar och deserialiserar dem. DataContractResolver Är ansluten till serialiseringsprocessen genom att skicka en instans av DataContractResolver-derived-klassen till DataContractSerializer konstruktorn, som du ser i följande exempel.

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

Exemplet serialiserar sedan CLR-typerna enligt följande kodexempel.

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

Exemplet deserialiserar sedan xsi:types enligt följande kodexempel.

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

Eftersom den anpassade DataContractResolver skickas till DataContractSerializer konstruktorn TryResolveType anropas under serialiseringen för att mappa en CLR-typ till en motsvarande xsi:type. ResolveName På samma sätt anropas under deserialisering för att mappa xsi:type till en motsvarande CLR-typ. I det här exemplet DataContractResolver definieras som i följande exempel.

Följande kodexempel är en klass som härleds från 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);
        }
    }
}

Som en del av exemplet genererar projektet Types sammansättningen med alla typer som används i det här exemplet. Använd det här projektet för att lägga till, ta bort eller ändra de typer som ska serialiseras.

Så här använder du det här exemplet

  1. Använd Visual Studio och öppna DCRSample.sln lösningsfilen.

  2. Tryck på F5 för att köra lösningen.

Se även