c# - .Net XmlSerializer: deserialize CDATA siendo el texto interno
xml-serialization (2)
Tengo un problema con la deserialización de CDATA usando .Net XmlSerializer estándar.
Actualización : recibo XML del sistema externo y no puedo influir en su formato, por lo que no puedo incluir CData en un Elemento de atributo por separado.
La serialización da esto:
<?xml version="1.0" encoding="utf-16"?>
<MyClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><![CDATA[Hello, world!]]></MyClass>
La deserialización no restaura el objeto a su estado original.
Aquí está la clase que se está serializando:
public class MyClass
{
string _data;
[XmlIgnore]
public string Data
{
get { return _data; }
set { _data = value; }
}
[XmlAnyElement]
public XmlCDataSection CData
{
get { return new XmlDataDocument().CreateCDataSection(Data); }
set { Data = value.Value; }
}
}
Aquí está la prueba que falla:
[Test]
public void CData_as_inner_text_test()
{
MyClass item = new MyClass();
item.Data = "Hello, world!";
XmlSerializer serializer = new XmlSerializer(item.GetType());
string serialized;
using (StringWriter sw = new StringWriter())
{
serializer.Serialize(sw, item);
serialized = sw.GetStringBuilder().ToString();
}
MyClass deserialized;
using (StringReader sr = new StringReader(serialized))
{
deserialized = (MyClass)serializer.Deserialize(sr);
}
Assert.AreEqual(item.Data, deserialized.Data); // For some reason, deserialized.Data == null
}
Encontré el mismo problema aquí, pero no hay respuesta: XmlSerializer, XmlAnyElement y CDATA
La propiedad CData termina nula, porque el contenido de la sección CDATA termina en la propiedad de Datos, donde se ignora ...
<MyClass><![CDATA[Hello, world!]]></MyClass>
es absolutamente equivalente a:
<MyClass>Hello, world!</MyClass>
No debería importar si la aplicación externa escribe el contenido de MyClass como CData o no. Del mismo modo, a la aplicación externa no le debe importar cómo la escriba.
IOW, esto debería ser todo lo que necesitas:
public class MyClass
{
string _data;
[XmlText]
public string Data
{
get { return _data; }
set { _data = value; }
}
}
Primero declare una propiedad como XmlCDataSection
public XmlCDataSection ProjectXml { get; set; }
en este caso projectXml es una cadena xml
ProjectXml = new XmlDocument().CreateCDataSection(projectXml);
cuando serialice su mensaje, tendrá su buen formato (aviso)
<?xml version="1.0" encoding="utf-16"?>
<MessageBase xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xsi:type="Message_ProjectStatusChanged">
<ID>131</ID>
<HandlerName>Plugin</HandlerName>
<NumRetries>0</NumRetries>
<TriggerXml><![CDATA[<?xml version="1.0" encoding="utf-8"?><TmData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Version="9.0.0" Date="2012-01-31T15:46:02.6003105" Format="1" AppVersion="10.2.0" Culture="en-US" UserID="0" UserRole=""><PROJECT></PROJECT></TmData>]]></TriggerXml>
<MessageCreatedDate>2012-01-31T20:28:52.4843092Z</MessageCreatedDate>
<MessageStatus>0</MessageStatus>
<ProjectId>0</ProjectId>
<UserGUID>8CDF581E44F54E8BAD60A4FAA8418070</UserGUID>
<ProjectGUID>5E82456F42DC46DEBA07F114F647E969</ProjectGUID>
<PriorStatus>0</PriorStatus>
<NewStatus>3</NewStatus>
<ActionDate>0001-01-01T00:00:00</ActionDate>
</MessageBase>