Problems serializing a class to XML and including a CDATA section

Clowner

New Member
I have a class that is serialized into XML for consumption by a web service. In this classes instance the XML must include a CDATA section for the web service to read it but I am at a loss on how to implement this.The XML needs to look like:\[code\]<UpdateOrderStatus> <Action>2</Action> <Value> <![CDATA[ <Shipment> <Header> <SellerID> ... ]]> </Value> </UpdateOrderStatus>\[/code\]I am able to generate the appropriate XML, except for the CDATA part. My class structure looks like: \[code\]public class UpdateOrderStatus{ public int Action { get; set; } public ValueInfo Value { get; set; } public UpdateOrderStatus() { Value = http://stackoverflow.com/questions/11471676/new ValueInfo(); } public class ValueInfo { public ShipmentInfo Shipment { get; set; } public ValueInfo() { Shipment = new ShipmentInfo(); } public class ShipmentInfo { public PackageListInfo PackageList { get; set; } public HeaderInfo Header { get; set; } public ShipmentInfo() { PackageList = new PackageListInfo(); Header = new HeaderInfo(); } ....\[/code\]I have seen some suggestions on using: \[code\][XmlElement("node", typeof(XmlCDataSection))]\[/code\]but that causes an exception I have also tried\[code\] [XmlElement("Value" + "<![CDATA[")]\[/code\]but the resulting XML is incorrect showing\[code\] <Value_x003C__x0021__x005B_CDATA_x005B_> .... </Value_x003C__x0021__x005B_CDATA_x005B_>\[/code\]Can anyone show me what I am doing wrong, or where I need to go with this? --Edit-- making shipmentInfo serializable per carlosfigueira works for the most part, however I get extra ? characters in the resulting XML ( see post Writing an XML fragment using XmlWriterSettings and XmlSerializer is giving an extra character for details ) As such I changed the Write XML method to: \[code\]public void WriteXml(XmlWriter writer) { using (MemoryStream ms = new MemoryStream()) { XmlSerializerNamespaces ns = new XmlSerializerNamespaces(); ns.Add("", ""); XmlWriterSettings settings = new XmlWriterSettings(); settings.OmitXmlDeclaration = true; settings.Encoding = new UnicodeEncoding(bigEndian: false, byteOrderMark: false); settings.Indent = true; using (XmlWriter innerWriter = XmlWriter.Create(ms, settings)) { shipmentInfoSerializer.Serialize(innerWriter, this.Shipment,ns); innerWriter.Flush(); writer.WriteCData(Encoding.UTF8.GetString(ms.ToArray())); } } }\[/code\]However I am not getting an exception: \[code\]System.InvalidOperationException: There was an error generating the XML document. ---> System.ArgumentException: '.', hexadecimalvalue 0x00, is an invalid character.\[/code\]--Edit -- The exception was caused by the inclusion of my previous serializeToString method. Since removing that the CDATA output is correct, except for a spacing issue, but I am also getting a namespace and xml declaration that should be removed by the XML settings specified. Output is:\[code\]<?xml version="1.0"?><UpdateOrderStatus xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <Action>1</Action> <Value><![CDATA[< S h i p m e n t I n f o > < P a c k a g e L i s t > < P a c k a g e > < S h i p D a t e > 2 0 1 2 - 0 7 - 1 3 T 1 1 : 5 8 : 5 1 . 0 9 2 5 6 1 5 - 0 4 : 0 0 < / S h i p D a t e > < I t e m L i s t > < I t e m > < S h i p p e d Q t y > 0 < / S h i p p e d Q t y > < / I t e m > < / I t e m L i s t > < / P a c k a g e > < / P a c k a g e L i s t > < H e a d e r > < S e l l e r I d > S h i p m e n t h e a d e r < / S e l l e r I d > < S O N u m b e r > 0 < / S O N u m b e r > < / H e a d e r > < / S h i p m e n t I n f o > ]]></Value></UpdateOrderStatus>\[/code\]Any ideas of avoiding the BOM using the new class? --Edit 3 -- SUCCESS!I have implemented changes suggested below and now have the following writer class and test methods: \[code\] UpdateOrderStatus obj = new UpdateOrderStatus(); obj.Action = 1; obj.Value = http://stackoverflow.com/questions/11471676/new UpdateOrderStatus.ValueInfo(); obj.Value.Shipment = new UpdateOrderStatus.ValueInfo.ShipmentInfo(); obj.Value.Shipment.Header.SellerId ="Shipment header"; obj.Value.Shipment.PackageList = new UpdateOrderStatus.ValueInfo.ShipmentInfo.PackageListInfo(); obj.Value.Shipment.PackageList.Package = new UpdateOrderStatus.ValueInfo.ShipmentInfo.PackageListInfo.PackageInfo(); obj.Value.Shipment.PackageList.Package.ShipDate = DateTime.Now; XmlSerializerNamespaces ns = new XmlSerializerNamespaces(); ns.Add("", ""); XmlWriterSettings settings = new XmlWriterSettings(); settings.OmitXmlDeclaration = true; settings.Encoding = new UTF8Encoding(false); settings.Indent = true; XmlSerializer xs = new XmlSerializer(typeof(UpdateOrderStatus)); MemoryStream ms = new MemoryStream(); XmlWriter writer = XmlWriter.Create(ms, settings); xs.Serialize(writer, obj, ns); Console.WriteLine(Encoding.UTF8.GetString(ms.ToArray())); }public void WriteXml(XmlWriter writer) { XmlSerializerNamespaces ns = new XmlSerializerNamespaces(); ns.Add("", ""); XmlWriterSettings settings = new XmlWriterSettings(); settings.OmitXmlDeclaration = true; settings.Indent = true; StringBuilder sb = new StringBuilder(); using (XmlWriter innerWriter = XmlWriter.Create(sb, settings)) { shipmentInfoSerializer.Serialize(innerWriter, this.Shipment, ns); innerWriter.Flush(); writer.WriteCData(sb.ToString()); } }\[/code\]This produces the following XML: \[code\]<UpdateOrderStatus> <Action>1</Action> <Value><![CDATA[<ShipmentInfo> <PackageList> <Package> <ShipDate>2012-07-13T14:05:36.6170802-04:00</ShipDate> <ItemList> <Item> <ShippedQty>0</ShippedQty> </Item> </ItemList> </Package> </PackageList> <Header> <SellerId>Shipment header</SellerId> <SONumber>0</SONumber> </Header></ShipmentInfo>]]></Value></UpdateOrderStatus>\[/code\]
 
Back
Top