.Net XmlSerializer: CDATA deserialization is internal text

I have a problem with CDATA deserialization using the standard .Net XmlSerializer.

Update . I get XML from an external system and I cannot influence its format, so I cannot include CData in a separate attribute element.

Serialization gives the following:

<?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> 

Deserialization does not restore the object to its original state.

Here is the class that is being serialized:

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

Here is a test that fails:

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

I found the same problem here, but no answer: XmlSerializer, XmlAnyElement and CDATA

+6
c # cdata xml-serialization
source share
2 answers

The CData property ends in null because the contents of the CDATA section ends in the Data property, where it is ignored ...

 <MyClass><![CDATA[Hello, world!]]></MyClass> 

absolutely equivalent:

 <MyClass>Hello, world!</MyClass> 

It doesn’t matter if the external application writes the contents of MyClass as CData or not. Similarly, an external application should not care how you write it.

IOW, this should be all you need:

 public class MyClass { string _data; [XmlText] public string Data { get { return _data; } set { _data = value; } } } 
+9
source share

First declare a property as XmlCDataSection

 public XmlCDataSection ProjectXml { get; set; } 

in this case projectXml is an xml string

 ProjectXml = new XmlDocument().CreateCDataSection(projectXml); 

when you serialize your message, you will have a good format (notification)

 <?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> 
0
source share

All Articles