title: Problems serializing a class to XML and including a CDATA section
body: <p>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.</p>
  
  <p>The XML needs to look like:</p>
  
  <pre><code>&lt;UpdateOrderStatus&gt; 
      &lt;Action&gt;2&lt;/Action&gt; 
          &lt;Value&gt; 
              &lt;![CDATA[ 
                  &lt;Shipment&gt; 
                      &lt;Header&gt; 
                          &lt;SellerID&gt;
                              ...
               ]]&gt;
           &lt;/Value&gt;
   &lt;/UpdateOrderStatus&gt;
  </code></pre>
  
  <p>I am able to generate the appropriate XML, except for the CDATA part. </p>
  
  <p>My class structure looks like: </p>
  
  <pre><code>public class UpdateOrderStatus
  {
      public int Action { get; set; }
  
  
      public ValueInfo Value { get; set; }
  
      public UpdateOrderStatus()
      {
          Value = 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></pre>
  
  <p>I have seen some suggestions on using: </p>
  
  <pre><code>[XmlElement("node", typeof(XmlCDataSection))]
  </code></pre>
  
  <p>but that causes an exception </p>
  
  <p>I have also tried</p>
  
  <pre><code> [XmlElement("Value" + "&lt;![CDATA[")]
  </code></pre>
  
  <p>but the resulting XML is incorrect showing</p>
  
  <pre><code> &lt;Value_x003C__x0021__x005B_CDATA_x005B_&gt;
   ....
   &lt;/Value_x003C__x0021__x005B_CDATA_x005B_&gt;
  </code></pre>
  
  <p>Can anyone show me what I am doing wrong, or where I need to go with this? </p>
  
  <p>--Edit-- </p>
  
  <p>making shipmentInfo serializable per carlosfigueira works for the most part, however I get extra ? characters in the resulting XML ( see post <a href="https://stackoverflow.com/questions/11456632/writing-an-xml-fragment-using-xmlwritersettings-and-xmlserializer-is-giving-an-e">Writing an XML fragment using XmlWriterSettings and XmlSerializer is giving an extra character</a> for details ) </p>
  
  <p>As such I changed the Write XML method to: </p>
  
  <pre><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></pre>
  
  <p>However I am not getting an exception: </p>
  
  <pre><code>System.InvalidOperationException: There was an error generating the XML document. ---&gt; System.ArgumentException: '.', hexadecimal
  value 0x00, is an invalid character.
  </code></pre>
  
  <p>--Edit -- </p>
  
  <p>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:</p>
  
  <pre><code>&lt;?xml version="1.0"?&gt;
  &lt;UpdateOrderStatus xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"&gt;
    &lt;Action&gt;1&lt;/Action&gt;
    &lt;Value&gt;&lt;![CDATA[&lt; S h i p m e n t I n f o &gt;
       &lt; P a c k a g e L i s t &gt;
           &lt; P a c k a g e &gt;
               &lt; S h i p D a t e &gt; 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 &lt; / S h i p D a t e &gt;
               &lt; I t e m L i s t &gt;
                   &lt; I t e m &gt;
                       &lt; S h i p p e d Q t y &gt; 0 &lt; / S h i p p e d Q t y &gt;
                   &lt; / I t e m &gt;
               &lt; / I t e m L i s t &gt;
           &lt; / P a c k a g e &gt;
       &lt; / P a c k a g e L i s t &gt;
       &lt; H e a d e r &gt;
           &lt; S e l l e r I d &gt; S h i p m e n t   h e a d e r &lt; / S e l l e r I d &gt;
           &lt; S O N u m b e r &gt; 0 &lt; / S O N u m b e r &gt;
       &lt; / H e a d e r &gt;
   &lt; / S h i p m e n t I n f o &gt; ]]&gt;&lt;/Value&gt;
  &lt;/UpdateOrderStatus&gt;
  </code></pre>
  
  <p>Any ideas of avoiding the BOM using the new class? </p>
  
  <p>--Edit 3 -- <strong>SUCCESS!</strong></p>
  
  <p>I have implemented changes suggested below and now have the following writer class and test methods: </p>
  
  <pre><code> UpdateOrderStatus obj = new UpdateOrderStatus();
  
          obj.Action = 1;
          obj.Value = 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></pre>
  
  <p>This produces the following XML: </p>
  
  <pre><code>&lt;UpdateOrderStatus&gt;
    &lt;Action&gt;1&lt;/Action&gt;
    &lt;Value&gt;&lt;![CDATA[&lt;ShipmentInfo&gt;
    &lt;PackageList&gt;
      &lt;Package&gt;
        &lt;ShipDate&gt;2012-07-13T14:05:36.6170802-04:00&lt;/ShipDate&gt;
        &lt;ItemList&gt;
          &lt;Item&gt;
            &lt;ShippedQty&gt;0&lt;/ShippedQty&gt;
          &lt;/Item&gt;
        &lt;/ItemList&gt;
      &lt;/Package&gt;
    &lt;/PackageList&gt;
    &lt;Header&gt;
      &lt;SellerId&gt;Shipment header&lt;/SellerId&gt;
      &lt;SONumber&gt;0&lt;/SONumber&gt;
    &lt;/Header&gt;
  &lt;/ShipmentInfo&gt;]]&gt;&lt;/Value&gt;
  &lt;/UpdateOrderStatus&gt;
  </code></pre>