Digamos que tenemos una estructura que se trata de datos es proporcionada por el conjunto de bytes no-administrado con Marshal.PtrToStructure.¿Cómo serializar la matriz de bytes a XML usando XmlSerializer en C#?
El diseño # struct C:
[StructLayout(LayoutKind.Sequential, Size = 128, CharSet = CharSet.Ansi, Pack = 1)]
public struct MNG_Y_Params
{
public byte Number;
public byte Version;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] OliNumber;
public byte InterfaceType;
}
La matriz de bytes representan una cadena (ASCII) en el código-un administrado.
Esta estructura es un miembro de otra estructura (que tiene algunos otros miembros):
public struct MyData
{
public int ID;
public StructType structType;
[XmlElement(ElementName="MNG_Y_Params")]
public MNG_Y_Params y_params;
[XmlElement(ElementName = "SimpleStruct2")]
public SimpleStruct2 ss2;
};
Así que también tenemos el código de apoyo
public class XMLIgnore
{
static public XmlSerializer customserialiser(MyData d)
{
XmlAttributes attrs = new XmlAttributes();
attrs.XmlIgnore = true;
XmlAttributeOverrides xmlOveride = new XmlAttributeOverrides();
switch (d.structType)
{
case StructType.ST_1:
xmlOveride.Add(typeof(MyData), "ss2", attrs);
break;
case StructType.ST_2:
xmlOveride.Add(typeof(MyData), "y_params", attrs);
break;
default:
break;
}
return new XmlSerializer(typeof(MyData), xmlOveride);
}
}
y el método Save
static void SaveToXml(object obj, string fileName, XmlSerializer writer)
{
//XmlSerializer writer = new XmlSerializer(obj.GetType());
using (StreamWriter file = new StreamWriter(fileName))
{
writer.Serialize(file, obj);
}
}
Por ejemplo, solo generaríamos algunos datos.
MNG_Y_Params yParams = new MNG_Y_Params();
yParams.Version = 1;
yParams.InterfaceType = 15;
yParams.Number = 35;
ASCIIEncoding enc = new ASCIIEncoding();
yParams.OliNumber = enc.GetBytes("#1");
MyData md1 = new MyData();
md1.ID = 1;
md1.structType = StructType.ST_1;
md1.y_params = yParams;
XmlSerializer writer = XMLIgnore.customserialiser(md1);
SaveToXml(md1, @"C:\temp\dataOne.xml", writer);
XML esperado:
<?xml version="1.0" encoding="utf-8"?>
<MyData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<ID>1</ID>
<structType>ST_1</structType>
<MNG_Y_Params>
<Number>35</Number>
<Version>1</Version>
<OliNumber>#1</OliNumber>
<InterfaceType>15</InterfaceType>
</MNG_Y_Params>
</MyData>
Resultado XML:
<?xml version="1.0" encoding="utf-8"?>
<MyData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<ID>1</ID>
<structType>ST_1</structType>
<MNG_Y_Params>
<Number>35</Number>
<Version>1</Version>
<OliNumber>IzE=</OliNumber>
<InterfaceType>15</InterfaceType>
</MNG_Y_Params>
</MyData>
Por favor, se centran en el (OliNumber) Resultado miembro de la matriz de bytes.
¿Hay un atributo que podríamos utilizar aquí? ¿Qué me estoy perdiendo?
Gracias por su tiempo y ayuda.
Ilan
Para reference
Al deserializar, es usted datos en OliNumber diferente de antes de la serialización? El valor en el XML puede ser bueno, tal vez solo sea el formato que XMLSerializer usa para la matriz de bytes. – Kipotlov
@Kipotlov Gracias por tu comentario. La deserialización funciona bien, sin embargo, el objetivo es representar en el XML los datos del código no administrado, donde el conjunto de bytes representa una cadena (ascii). –
El serializador trata 'byte []' como datos binarios, no como una cadena, por lo que utiliza la codificación de transferencia (base64) para permitir que los datos binarios arbitrarios pasen a través de XML. Lea la especificación, XML no permite la mayoría de los caracteres que no se imprimen en el contenido. Si está enviando una cadena, llámelo 'String'. –