在C#中自定义反序列化样本?

时间:2009-02-23 01:44:11

标签: c# xml serialization

我正在寻找一个示例,它可以让我将以UTF-8编码的XML流反序列化为类的字段。更具体地说,我有一个类,

class Foo
{
    string abc;
    byte[] bcd;
}

和abc映射到XML元素“Abc”并且bcd映射到XML元素“Bcd”,我想获取bcd的流并检索字节(从XML流直接获取相关元素“Bcd”)以手动操作/以定制的方式。

我正在寻找一个样本,但是失败了,任何人都可以帮我指一个相关的样本或写一些伪代码吗?

编辑:XML是来自服务器的SOAP reaponse,在响应中有一个响应XML元素(我的样本中的元素Bcd),它由服务器端的UTF-8编码,但由于Http Web Services将在客户端使用base64所以,每当我在客户端收到这样的“字节”时,自动生成的Web服务代理就会抛出异常,表示base64编码中的XML元素无效。所以,我正在考虑如何使用base64编码覆盖默认值以解码字节,这就是我问这个问题的原因。如果有一种方法可以接受流或类似的东西代表相关响应元素的在线字节(我的样本中的Bcd)并让我操纵,那就太棒了!

提前谢谢, 乔治

2 个答案:

答案 0 :(得分:4)

This article非常擅长解释如何在C#中处理XML序列化。

答案 1 :(得分:3)

IXmlSerializable是一个选项(但不是很有趣),但它感觉就像在这种情况下属性提供了大部分需要的东西而没有额外的工作:

[Serializable]
public class Foo
{
    public string Abc {get;set;}
    private byte[] bcd;
    public byte[] Bcd {
        get {return bcd;}
        set {/* your code (with `value`) here */ }
    }
}

重新布线格式(base64等);你试过通过xsd.exe运行它吗?它可能会让你大吃一惊并且做对了......但是是的;在IXmlSerializable范围内,您可以选择ReadContentAsBase64ReadContentAsBinHex等。但这非常难看;类似的东西(对于简单版本):

[Serializable]
public class Foo : IXmlSerializable
{
    public Foo() { }
    public Foo(string abc, byte[] bcd)
    {
        Abc = abc;
        Bcd = bcd;
    }
    public string Abc { get; private set; }
    public byte[] Bcd { get; private set; }

    XmlSchema IXmlSerializable.GetSchema()
    {
        return null;
    }

    void IXmlSerializable.WriteXml(System.Xml.XmlWriter writer)
    {
        if (Abc != null)
        {
            writer.WriteElementString("Abc", Abc);
        }
        if (Bcd != null)
        {
            writer.WriteStartElement("Bcd");
            writer.WriteBase64(Bcd, 0, Bcd.Length);
            writer.WriteEndElement();
        }
    }
    void IXmlSerializable.ReadXml(System.Xml.XmlReader reader)
    {
        reader.ReadStartElement();
        reader.ReadStartElement("Abc");
        Abc = reader.ReadString();
        reader.ReadEndElement();
        reader.ReadStartElement("Bcd");
        MemoryStream ms = null;
        byte[] buffer = new byte[256];
        int bytesRead;
        while ((bytesRead = reader.ReadContentAsBase64(
            buffer, 0, buffer.Length)) > 0)
        {
            if (ms == null) ms = new MemoryStream(bytesRead);
            ms.Write(buffer, 0, bytesRead);
        }
        if (ms != null) Bcd = ms.ToArray();
        reader.ReadEndElement(); 
    }
}