是否可以在不实现IXmlSerializable的情况下为XmlSerializer提供自定义序列化? [英] Can I provide custom serialization for XmlSerializer without implementing IXmlSerializable?

查看:151
本文介绍了是否可以在不实现IXmlSerializable的情况下为XmlSerializer提供自定义序列化?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们正在使用 XmlSerializer ,我想为某些类提供自定义序列化。但是,我并不总是能够修改相关类的源代码,否则我只能使其实现 IXmlSerializable

We're using XmlSerializer, and I want to provide custom serialization for certain classes. However, I don't always have the ability to modify the source code of the class in question, otherwise I could just make it implement IXmlSerializable. Is there any way to do this?

推荐答案

下面是代理反序列化助手的一个简单示例:

Here's a simple example of the proxy deserialize helper:

给出了一个我们不能直接在类级别控制序列化的类型:

Given a type that we cannot directly control serialization of at the class level:

public sealed class Class //contrived example
{
    public string Property {get;set;}
}

和我们需要反序列化的xml:

And the xml we need to deserialize with:

<Class>
  <Property>Value</Property>
</Class>

您可以创建代理类型来手动处理目标类型的反序列化过程,如下所示:

You could create a proxy type to manually process the deserialization process of the target type like so:

[XmlRoot("Class")] // <-- Very important
public sealed class ClassSerializerProxy : IXmlSerializable
{
    public Class ClassValue {get;set;}

    public System.Xml.Schema.XmlSchema GetSchema(){return null;}
    public void WriteXml(System.Xml.XmlWriter writer){}

    public void ReadXml(System.Xml.XmlReader reader)
    {
        var x = XElement.ReadFrom(reader) as XElement;
        this.ClassValue = new Class();
        //again this is a simple contrived example
        this.ClassValue.Property = x.XPathSelectElement("Property").Value;
    }
}

用法是:

void Main()
{
    // get the xml value somehow
    var xdoc= XDocument.Parse(@"<Class><Property>Value</Property></Class>");

    // deserialize the xml into the proxy type
    var proxy = Deserialize<ClassSerializerProxy>(xdoc);

    // read the resulting value
    var value = proxy.ClassValue;
}

public object Deserialize(XDocument xmlDocument, Type DeserializeToType)
{
    XmlSerializer xmlSerializer = new XmlSerializer(DeserializeToType);
    using (XmlReader reader = xmlDocument.CreateReader())
        return xmlSerializer.Deserialize(reader);
}

现在抛出一些泛型和扩展方法,我们可以清理调用最终版本(例外处理)版本:

Now throw in some generics and an extension method, and we can clean the call site up a bit for a final (EXCEPT EXCEPTION HANDLING) version:

用法:

void Main()
{
    var xml = @"<Class><Property>Value</Property></Class>";

    var value = xml.DeserializeWithProxy<ClassSerializerProxy,Class>();

    value.Dump();
}

您的实例类型:

public sealed class Class
{
    public string Property {get;set;}
}

代理类型必须实现的接口

An interface that proxy types must implement

public interface ISerializerProxy<TInstanceType> where TInstanceType : class
{
    TInstanceType Value { get; }
}

示例代理现在实现了新接口

The example proxy now implements the new interface

[XmlRoot("Class")]
public sealed class ClassSerializerProxy : IXmlSerializable, ISerializerProxy<Class>
{
    public Class Value {get;set;}

    public System.Xml.Schema.XmlSchema GetSchema(){return null;}
    public void WriteXml(System.Xml.XmlWriter writer){}

    public void ReadXml(System.Xml.XmlReader reader)
    {
        var x = XElement.ReadFrom(reader) as XElement;
        this.Value = new Class();
        this.Value.Property = x.XPathSelectElement("Property").Value;
    }
}

反序列化方法现在是<$的扩展方法c $ c> string ,可以与任何代理类型一起使用。

The deserialization method is now an extension method on string and can be used with any proxy type.

public static class ExtensionMethods
{
    public static TInstanceType DeserializeWithProxy<TProxyType,TInstanceType>(this string xml) 
        where TProxyType : ISerializerProxy<TInstanceType> 
        where TInstanceType : class
    {
        using (XmlReader reader = XDocument.Parse(xml).CreateReader())
        {
            var xmlSerializer = new XmlSerializer(typeof(TProxyType));
            return (xmlSerializer.Deserialize(reader) as ISerializerProxy<TInstanceType>).Value;
        }
    }
}

这篇关于是否可以在不实现IXmlSerializable的情况下为XmlSerializer提供自定义序列化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆