title: Deserialize Nested XML with Web Api MVC 4
body: <p>I have the following XML which I am attempting to deserialize to an order object with MVC 4 Web Api with .Net Framework 4.5... but when I send this XML using POST from Chrome Advanced Rest Client with Content-Type set to application/xml the order data is null at the server (It does appear to work if I send the sample xml generated by the Web Api Help page). How can I deserialize the original xml without changing it?</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8" ?&gt;
      &lt;order&gt;
      &lt;header&gt;
          &lt;organization id="1"&gt;&lt;/organization&gt;
          &lt;customerClient id=""&gt;&lt;/customerClient&gt;
          &lt;date&gt;05/06/14&lt;/date&gt;
          &lt;customerOrderNumber&gt;123-4567-8901&lt;/customerOrderNumber&gt;
          &lt;number&gt;abc-1234&lt;/number&gt;
                  &lt;OriginalNumber&gt;&lt;/OriginalNumber&gt;
                  &lt;status id="0"&gt;&lt;/status&gt;
          &lt;billing-info&gt;
              &lt;name&gt;A Person&lt;/name&gt;
              &lt;address1&gt;123 Main Street&lt;/address1&gt;
              &lt;address2&gt;&lt;/address2&gt;
              &lt;city&gt;Cityville&lt;/city&gt;
              &lt;state&gt;AK&lt;/state&gt;
              &lt;zip&gt;55555&lt;/zip&gt;
              &lt;country&gt;US&lt;/country&gt;
              &lt;phone&gt;5555551212&lt;/phone&gt;
              &lt;emailAddress&gt;aperson@gmail.com&lt;/emailAddress&gt;
              &lt;cc number="" exp="" ccv="" amt=""&gt;&lt;/cc&gt;
          &lt;/billing-info&gt;
      &lt;/header&gt;
      &lt;data&gt;
          &lt;shipments&gt;
              &lt;shipment&gt;
                  &lt;shipping-info&gt;
                      &lt;name&gt;A Person&lt;/name&gt;
                      &lt;address1&gt;123 Main Street&lt;/address1&gt;
                      &lt;address2&gt;&lt;/address2&gt;
                      &lt;city&gt;Cityville&lt;/city&gt;
                      &lt;state&gt;AK&lt;/state&gt;
                      &lt;zip&gt;55555&lt;/zip&gt;
                      &lt;country&gt;US&lt;/country&gt;
                      &lt;phone&gt;&lt;/phone&gt;
                      &lt;emailAddress&gt;aperson@gmail.com&lt;/emailAddress&gt;
                      &lt;method&gt;13&lt;/method&gt;
                      &lt;shipCharge&gt;2.00&lt;/shipCharge&gt;
                  &lt;/shipping-info&gt;
                  &lt;gift-note&gt;&lt;/gift-note&gt;
                  &lt;ship-attributes&gt;&lt;/ship-attributes&gt;
                  &lt;products&gt;
                      &lt;line-item number="1"&gt;
                          &lt;mc_order&gt;&lt;/mc_order&gt;
                          &lt;sku&gt;ABC123&lt;/sku&gt;
                          &lt;quantity&gt;1&lt;/quantity&gt;
                          &lt;description&gt;&lt;/description&gt;
                          &lt;images&gt;
                              &lt;image no="1"&gt;
                                  &lt;url&gt;http://pictures.com/123/page1.jpg&lt;/url&gt;
                              &lt;/image&gt;
                              &lt;image no="2"&gt;
                                  &lt;url&gt;http://pictures.com/123/page1.jpg&lt;/url&gt;
                              &lt;/image&gt;
                          &lt;/images&gt;
                          &lt;attributes&gt;
                              &lt;attribute id="123"&gt;&lt;/attribute&gt;
                          &lt;/attributes&gt;
                      &lt;/line-item&gt;
                  &lt;/products&gt;
              &lt;/shipment&gt;
          &lt;/shipments&gt;
      &lt;/data&gt;
  &lt;/order&gt;
  </code></pre>
  
  <p>The XML schema is set in stone I am not allowed to modify it.</p>
  
  <p>I have pasted XML As Classes to my Web Api project in Visual Studio 2012 and it created this:</p>
  
  <pre><code>using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Web;
  using System.Xml.Serialization;
  
  namespace MyProject.Models
  {
  
      /// &lt;remarks/&gt;
      [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
      [System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
      public partial class order
      {
  
          private orderHeader headerField;
  
          private orderData dataField;
  
          /// &lt;remarks/&gt;
          public orderHeader header
          {
              get
              {
                  return this.headerField;
              }
              set
              {
                  this.headerField = value;
              }
          }
  
          /// &lt;remarks/&gt;
          public orderData data
          {
              get
              {
                  return this.dataField;
              }
              set
              {
                  this.dataField = value;
              }
          }
      }
  
      /// &lt;remarks/&gt;
      [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
      public partial class orderHeader
      {
  
          private orderHeaderOrganization organizationField;
  
          private orderHeaderCustomerClient customerClientField;
  
          private string dateField;
  
          private string customerOrderNumberField;
  
          private string numberField;
  
          private object originalNumberField;
  
          private orderHeaderStatus statusField;
  
          private orderHeaderBillinginfo billinginfoField;
  
          /// &lt;remarks/&gt;
          public orderHeaderOrganization organization
          {
              get
              {
                  return this.organizationField;
              }
              set
              {
                  this.organizationField = value;
              }
          }
  
          /// &lt;remarks/&gt;
          public orderHeaderCustomerClient customerClient
          {
              get
              {
                  return this.customerClientField;
              }
              set
              {
                  this.customerClientField = value;
              }
          }
  
          /// &lt;remarks/&gt;
          public string date
          {
              get
              {
                  return this.dateField;
              }
              set
              {
                  this.dateField = value;
              }
          }
  
          /// &lt;remarks/&gt;
          public string customerOrderNumber
          {
              get
              {
                  return this.customerOrderNumberField;
              }
              set
              {
                  this.customerOrderNumberField = value;
              }
          }
  
          /// &lt;remarks/&gt;
          public string number
          {
              get
              {
                  return this.numberField;
              }
              set
              {
                  this.numberField = value;
              }
          }
  
          /// &lt;remarks/&gt;
          public object OriginalNumber
          {
              get
              {
                  return this.originalNumberField;
              }
              set
              {
                  this.originalNumberField = value;
              }
          }
  
          /// &lt;remarks/&gt;
          public orderHeaderStatus status
          {
              get
              {
                  return this.statusField;
              }
              set
              {
                  this.statusField = value;
              }
          }
  
          /// &lt;remarks/&gt;
          [System.Xml.Serialization.XmlElementAttribute("billing-info")]
          public orderHeaderBillinginfo billinginfo
          {
              get
              {
                  return this.billinginfoField;
              }
              set
              {
                  this.billinginfoField = value;
              }
          }
      }
  
      /// &lt;remarks/&gt;
      [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
      public partial class orderHeaderOrganization
      {
  
          private byte idField;
  
          /// &lt;remarks/&gt;
          [System.Xml.Serialization.XmlAttributeAttribute()]
          public byte id
          {
              get
              {
                  return this.idField;
              }
              set
              {
                  this.idField = value;
              }
          }
      }
  
      /// &lt;remarks/&gt;
      [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
      public partial class orderHeaderCustomerClient
      {
  
          private string idField;
  
          /// &lt;remarks/&gt;
          [System.Xml.Serialization.XmlAttributeAttribute()]
          public string id
          {
              get
              {
                  return this.idField;
              }
              set
              {
                  this.idField = value;
              }
          }
      }
  
      /// &lt;remarks/&gt;
      [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
      public partial class orderHeaderStatus
      {
  
          private byte idField;
  
          /// &lt;remarks/&gt;
          [System.Xml.Serialization.XmlAttributeAttribute()]
          public byte id
          {
              get
              {
                  return this.idField;
              }
              set
              {
                  this.idField = value;
              }
          }
      }
  
      /// &lt;remarks/&gt;
      [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
      public partial class orderHeaderBillinginfo
      {
  
          private string nameField;
  
          private string address1Field;
  
          private object address2Field;
  
          private string cityField;
  
          private string stateField;
  
          private ushort zipField;
  
          private string countryField;
  
          private ulong phoneField;
  
          private string emailAddressField;
  
          private orderHeaderBillinginfoCC ccField;
  
          /// &lt;remarks/&gt;
          public string name
          {
              get
              {
                  return this.nameField;
              }
              set
              {
                  this.nameField = value;
              }
          }
  
          /// &lt;remarks/&gt;
          public string address1
          {
              get
              {
                  return this.address1Field;
              }
              set
              {
                  this.address1Field = value;
              }
          }
  
          /// &lt;remarks/&gt;
          public object address2
          {
              get
              {
                  return this.address2Field;
              }
              set
              {
                  this.address2Field = value;
              }
          }
  
          /// &lt;remarks/&gt;
          public string city
          {
              get
              {
                  return this.cityField;
              }
              set
              {
                  this.cityField = value;
              }
          }
  
          /// &lt;remarks/&gt;
          public string state
          {
              get
              {
                  return this.stateField;
              }
              set
              {
                  this.stateField = value;
              }
          }
  
          /// &lt;remarks/&gt;
          public ushort zip
          {
              get
              {
                  return this.zipField;
              }
              set
              {
                  this.zipField = value;
              }
          }
  
          /// &lt;remarks/&gt;
          public string country
          {
              get
              {
                  return this.countryField;
              }
              set
              {
                  this.countryField = value;
              }
          }...you get the idea, it's too long to post here.
  </code></pre>
  
  <p>The Web Api Help Page shows a sample of the acceptable XML input which looks like this:</p>
  
  <pre><code>&lt;order xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/MyProject.Models"&gt;
    &lt;data&gt;
      &lt;shipments&gt;
        &lt;shipment&gt;
          &lt;giftnote /&gt;
          &lt;products&gt;
            &lt;lineitem&gt;
              &lt;attributes&gt;
                &lt;attribute&gt;
                  &lt;id&gt;64&lt;/id&gt;
                &lt;/attribute&gt;
              &lt;/attributes&gt;
              &lt;description /&gt;
              &lt;images&gt;
                &lt;orderDataShipmentsShipmentProductsLineitemImage&gt;
                  &lt;no&gt;64&lt;/no&gt;
                  &lt;url&gt;sample string 1&lt;/url&gt;
                &lt;/orderDataShipmentsShipmentProductsLineitemImage&gt;
                &lt;orderDataShipmentsShipmentProductsLineitemImage&gt;
                  &lt;no&gt;64&lt;/no&gt;
                  &lt;url&gt;sample string 1&lt;/url&gt;
                &lt;/orderDataShipmentsShipmentProductsLineitemImage&gt;
                &lt;orderDataShipmentsShipmentProductsLineitemImage&gt;
                  &lt;no&gt;64&lt;/no&gt;
                  &lt;url&gt;sample string 1&lt;/url&gt;
                &lt;/orderDataShipmentsShipmentProductsLineitemImage&gt;
              &lt;/images&gt;
              &lt;mc_order /&gt;
              &lt;number&gt;64&lt;/number&gt;
              &lt;quantity&gt;64&lt;/quantity&gt;
              &lt;sku&gt;sample string 2&lt;/sku&gt;
            &lt;/lineitem&gt;
          &lt;/products&gt;
          &lt;shipattributes /&gt;
          &lt;shippinginfo&gt;
            &lt;address1&gt;sample string 2&lt;/address1&gt;
            &lt;address2 /&gt;
            &lt;city&gt;sample string 4&lt;/city&gt;
            &lt;country&gt;sample string 7&lt;/country&gt;
            &lt;emailAddress&gt;sample string 9&lt;/emailAddress&gt;
            &lt;method&gt;64&lt;/method&gt;
            &lt;name&gt;sample string 1&lt;/name&gt;
            &lt;phone /&gt;
            &lt;shipCharge&gt;11&lt;/shipCharge&gt;
            &lt;state&gt;sample string 5&lt;/state&gt;
            &lt;zip&gt;6&lt;/zip&gt;
          &lt;/shippinginfo&gt;
        &lt;/shipment&gt;
      &lt;/shipments&gt;
    &lt;/data&gt;
    &lt;header&gt;
      &lt;OriginalNumber /&gt;
      &lt;billinginfo&gt;
        &lt;address1&gt;sample string 2&lt;/address1&gt;
        &lt;address2 /&gt;
        &lt;cc&gt;
          &lt;amt&gt;sample string 4&lt;/amt&gt;
          &lt;ccv&gt;sample string 3&lt;/ccv&gt;
          &lt;exp&gt;sample string 2&lt;/exp&gt;
          &lt;number&gt;sample string 1&lt;/number&gt;
        &lt;/cc&gt;
        &lt;city&gt;sample string 4&lt;/city&gt;
        &lt;country&gt;sample string 7&lt;/country&gt;
        &lt;emailAddress&gt;sample string 9&lt;/emailAddress&gt;
        &lt;name&gt;sample string 1&lt;/name&gt;
        &lt;phone&gt;8&lt;/phone&gt;
        &lt;state&gt;sample string 5&lt;/state&gt;
        &lt;zip&gt;6&lt;/zip&gt;
      &lt;/billinginfo&gt;
      &lt;customerClient&gt;
        &lt;id&gt;sample string 1&lt;/id&gt;
      &lt;/customerClient&gt;
      &lt;customerOrderNumber&gt;sample string 2&lt;/customerOrderNumber&gt;
      &lt;date&gt;sample string 1&lt;/date&gt;
      &lt;number&gt;sample string 3&lt;/number&gt;
      &lt;organization&gt;
        &lt;id&gt;64&lt;/id&gt;
      &lt;/organization&gt;
      &lt;status&gt;
        &lt;id&gt;64&lt;/id&gt;
      &lt;/status&gt;
    &lt;/header&gt;
  &lt;/order&gt;
  </code></pre>
  
  <p>Here is the controller code:</p>
  
  <pre><code>using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Net;
  using System.Net.Http;
  using System.Web;
  using System.Web.Http;
  using System.Web.Mvc;
  using MyProject.Models;
  
  namespace MyProject.Controllers
  {
      public class LegacyOrdersController : ApiController
      {
          static readonly ILegacyOrderRepository repository = new LegacyOrderRepository();
  
          public HttpResponseMessage PostOrder([FromBody]order order) &lt;--this is null
          {
              order = repository.Add(order);
              var response = Request.CreateResponse&lt;order&gt;(HttpStatusCode.Created, order);
  
              string uri = Url.Link("DefaultApi", new { id = order.header.customerOrderNumber });
              response.Headers.Location = new Uri(uri);
              return response;
          }
      }
  }
  </code></pre>