«Метод ReadElementContentAsBase64 не поддерживается в этом XmlReader» - PullRequest
8 голосов
/ 22 сентября 2010
using System.IO;
using System.Runtime.Serialization;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;

namespace XmlTest
{
    class TestClass : IXmlSerializable
    {
        public XmlSchema GetSchema()
        {
            return null;
        }

        public void ReadXml(XmlReader reader)
        {
            var data = new byte[3];
            reader.ReadStartElement();
            reader.ReadElementContentAsBase64(data, 0, data.Length);
        }

        public void WriteXml(XmlWriter writer)
        {
            var data = new byte[] { 1, 2, 3 };
            writer.WriteBase64(data, 0, data.Length);
        }

        public static void Main()
        {
            var serializer = new DataContractSerializer(typeof(TestClass));

            var stringWriter = new StringWriter();
            using (var writer = XmlWriter.Create(stringWriter))
            {
                serializer.WriteObject(writer, new TestClass());
            }

            var stringReader = new StringReader(stringWriter.ToString());
            using (var reader = XmlReader.Create(stringReader))
            {
                serializer.ReadObject(reader, true);
            }
        }
    }
}

В строке ReadElementContentAsBase64 отображается NotSupportedException с сообщением:

Метод ReadElementContentAsBase64 не поддерживается в этом XmlReader. Используйте свойство CanReadBinaryContent, чтобы узнать, реализует ли его читатель.

(я проверил, и CanReadBinaryContent возвращает true)

Я использую реализацию платформы Microsoft .NET 3.5.

Что может быть причиной этого?

Примечание. Я намеренно смешиваю DataContractSerializer с IXmlSerializable. Я понимаю, что более распространенный подход для DataContractSerializer - сделать мой класс [DataContract].

Редактировать: Я сейчас использую обходной путь:
Convert.FromBase64String(reader.ReadElementContentAsString())
Тем не менее, я удивляюсь, почему обычный путь терпит неудачу.

Ответы [ 2 ]

7 голосов
/ 22 марта 2011

Я также столкнулся с этой проблемой.XmlReader, созданный linq doc.CreateReader(), не поддерживает декодирование Base64.Я обошел его, сначала сохранив в MemoryStream и создав из него XmlReader:

     Stream s = new MemoryStream();
     XmlSerializer serializer = new XmlSerializer(typeof(SerializableDocument));   
     document.Save(s);
     s.Seek(0, SeekOrigin.Begin);

     using (XmlReader newReader = XmlReader.Create(s))
     {
        SerializableDocument serializableDocument = (SerializableDocument)serializer.Deserialize(newReader);
        // do stuff with it
     }
3 голосов
/ 23 февраля 2013

Я взял ответ Роберта и превратил его в метод расширения, наслаждайтесь!

public static T DeserializeWithBinaryData<T>(this XElement el)
{
    var xDoc = el.ToXmlDocument();
    using (var ms = new MemoryStream())
    {
        xDoc.Save(ms);
        ms.Seek(0, SeekOrigin.Begin);
        var serializer = new XmlSerializer(typeof (T));
        return (T)serializer.Deserialize(ms);
    }
}
...