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

La linea ReadElementContentAsBase64 tiri NotSupportedException con il messaggio:"metodo ReadElementContentAsBase64 non è supportato su questo XmlReader"

metodo ReadElementContentAsBase64 non è supportato su questo XmlReader. Utilizzare la proprietà CanReadBinaryContent per scoprire se un lettore lo implementa.

(ho controllato, e CanReadBinaryContent restituisce True)

sto usando l'attuazione 3.5 framework Microsoft .NET.

Cosa potrebbe causare questo?

Nota: Sto mescolando intenzionalmente DataContractSerializer con IXmlSerializable. Mi rendo conto che l'approccio più comune per DataContractSerializer è quello di rendere la mia classe un [DataContract].

Edit: Ora sto utilizzando una soluzione:
Convert.FromBase64String(reader.ReadElementContentAsString())
Eppure, mi chiedo perché il modo normale non riesce.

+0

Alla fine hai risolto questo problema? Ho esattamente lo stesso problema ('CanReadBinaryContent' è' true', ma non riesce ancora), ma in aggiunta, non ho accesso al serializzatore che si blocca effettivamente (ho incorporato un oggetto che implementa 'IXmlSerializable' in un' DataContract'). – Christoph

risposta

6

Ho riscontrato anche questo problema. XmlReader creato da linq doc.CreateReader() non implementa la decodifica Base64. Ho ottenuto intorno ad esso in primo luogo il risparmio a un MemoryStream e la creazione di un XmlReader da quella:

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

ho preso la risposta di Robert e lo ha trasformato un metodo di estensione, buon divertimento!

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