настроить образец десериализации в C #? - PullRequest
2 голосов
/ 23 февраля 2009

Я ищу образец, который позволил бы мне десериализовать поток XML, закодированный в UTF-8, в поле класса. Точнее, у меня есть класс, как,

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

и abc сопоставляется с элементом XML «Abc», а bcd сопоставляется с элементом XML «Bcd», и я хочу получить поток для bcd и получить байты (из потока XML для связанного элемента «Bcd» напрямую) для манипуляции вручную / по индивидуальному заказу.

Я ищу образец, но не смог, кто-нибудь может помочь указать мне на связанный образец или написал какой-то псевдокод?

Редактировать: XML является SOAP ответом от сервера, в ответе есть один ответный XML-элемент (элемент Bcd в моем примере), который кодируется UTF-8 со стороны сервера, но поскольку веб-службы Http будут использовать base64 на клиенте сторона, поэтому каждый раз, когда я получаю такие «байты» на стороне клиента, и автоматически сгенерированный прокси-сервер веб-служб будет выдавать исключение, говорящее о недопустимом элементе XML в кодировке base64. Итак, я думаю о том, как переписать значение по умолчанию, используя кодировку base64 для декодирования байтов, и именно поэтому я задаю этот вопрос. Если мог бы быть способ принять поток или что-то подобное, представляющее байты на проводе связанных элементов ответа (Bcd в моем примере), и позвольте мне манипулировать, это будет так здорово!

спасибо заранее, George

Ответы [ 2 ]

4 голосов
/ 23 февраля 2009

Эта статья очень хорошо объясняет, как обрабатывать сериализацию XML в C #.

3 голосов
/ 23 февраля 2009

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 у вас будет выбор ReadContentAsBase64, ReadContentAsBinHex и т. д. Но это очень уродливо; что-то вроде (для простой версии):

[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(); 
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...