Reputation: 45801
I am looking for a sample, which could let me deserialize an XML stream encoded in UTF-8 into a field of a class. More specifically, I have a class like,
class Foo
{
string abc;
byte[] bcd;
}
and abc maps to XML element "Abc" and bcd maps to XML element "Bcd", and I want to get the stream for bcd and retrieve bytes (from XML stream for related element "Bcd" directly) to manipulate manually/in a customized way.
I am looking for a sample, but failed, could anyone help to point me to a related sample or wrote some pseudo code?
Edit: the XML is SOAP reaponse from server, in the response there is one response XML element (element Bcd in my sample) which is encoded by UTF-8 from server side, but since Http Web Services will use base64 at client side, so each time I receive such "bytes" at client side and the automatically generated web services proxy will throw exception says invalid XML element in base64 encoding. So, I am thinking about how to overwrite the default using base64 encoding to decode the bytes, and this is why I ask this question. If there could be a way to accept stream or something similar represents the on-wire bytes of the related response elements (Bcd in my sample) and let me manipulate, it will be so great!
thanks in advance, George
Upvotes: 2
Views: 3613
Reputation: 1064114
IXmlSerializable
is one option (but not much fun), but it feels like in this case properties offer most of what is wanted without extra work:
[Serializable]
public class Foo
{
public string Abc {get;set;}
private byte[] bcd;
public byte[] Bcd {
get {return bcd;}
set {/* your code (with `value`) here */ }
}
}
Re the wire format (base64 etc); have you tried just running it through xsd.exe? It might surprise you and get it right... but yes; within IXmlSerializable
you will have your choice of ReadContentAsBase64
, ReadContentAsBinHex
, etc. But it is very ugly; something like (for a simple version):
[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();
}
}
Upvotes: 3