c# .net xml-serialization cdata

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>