0

I have a controller which contains POST method that have to receive an XML object and deserialize it. But after all my attempts I am always getting an empty object with all properties set to nulls or defaults.

Here is the code (sorry for this heap, but I think the mistake could be in any piece of the code.):

Order class:

[XmlRoot]
public class Order
{
    [XmlElement]
    public long OrderSource { get; set; }

    [XmlElement]
    public long Type { get; set; }

    [XmlElement]
    public decimal DiscountPercent { get; set; }

    [XmlElement]
    public string PayMethod { get; set; }

    [XmlElement]
    public int QtyPerson { get; set; }

    [XmlElement]
    public decimal ChangeAmount { get; set; }

    [XmlElement]
    public string Remark { get; set; }

    [XmlElement]
    public Customer Customer { get; set; }

    [XmlElement]
    public Address Address { get; set; }

    [XmlElement]
    public string AddressRemark { get; set; }

    [XmlElement]
    public Phone Phone { get; set; }

    [XmlArray(nameof(Products))]
    public List<Product> Products { get; set; }

Customer class:

[XmlRoot]
public class Customer
{
    [XmlElement]
    public string Name { get; set; }
}

Address class:

[XmlRoot]
public class Address
{
    [XmlElement]
    public string CityName { get; set; }

    [XmlElement]
    public string StreetName { get; set; }

    [XmlElement]
    public string House { get; set; }

    [XmlElement]
    public string Flat { get; set; }

    [XmlElement]
    public string Floor { get; set; }

    [XmlElement]
    public string DoorCode { get; set; }
}

And the Phone class:

[XmlRoot]
public class Phone
{
    [XmlElement]
    public string Number { get; set; }
}

And here is the body of the request:

<?xml version="1.0" encoding="UTF-8"?>
<Order>
    <orderSource>0</orderSource>
    <type>0</type>
    <discountPercent>0</discountPercent>
    <payMethod>string</payMethod>
    <qtyPerson>0</qtyPerson>
    <changeAmount>0</changeAmount>
    <remark>string</remark>
    <customer>
        <name>asdasd</name>
    </customer>
    <address>
        <cityName>string</cityName>
        <streetName>string</streetName>
        <house>string</house>
        <flat>string</flat>
        <floor>string</floor>
        <doorCode>string</doorCode>
    </address>
    <addressRemark>string</addressRemark>
    <phone>
        <number>string</number>
    </phone>
    <products>
        <name>string</name>
        <code>string</code>
        <qty>0</qty>
        <price>0</price>
    </products>
</Order>

Tell me please, what should I change here, so the built-in deserializer could properly process the request? Thanks in advance

Arthur Edgarov
  • 473
  • 5
  • 16
  • Your problem is that the **case** of your XML elements does not match the XML. Your properties are pascal cased but the XML is camel cased. And, unfortunately, XML is case-sensitive. See: [Is XML case-sensitive?](https://stackoverflow.com/q/7414747/3744182) (answer: yes) and [Case insensitive XML parser in c#](https://stackoverflow.com/q/9334771/3744182). – dbc Nov 17 '20 at 04:40
  • You need to fix your property names or override them by setting setting [`XmlElementAttribute.ElementName`](https://learn.microsoft.com/en-us/dotnet/api/system.xml.serialization.xmlelementattribute.elementname) as shown [here](https://stackoverflow.com/a/36505504), e.g. `[XmlElement("orderSource")]` – dbc Nov 17 '20 at 04:41
  • 1
    @dbc Thanks! That worked for me! Would You mind posting an answer, so I would be able to mark it as the correct one? – Arthur Edgarov Nov 17 '20 at 09:43

1 Answers1

1

Your problem is that the case of your XML elements does not match the XML. Your properties are pascal cased but the XML is camel cased. And, unfortunately, XML is case-sensitive. See: Is XML case-sensitive? (answer: yes) and Case insensitive XML parser in c#.

You need to fix your property names or override them by setting setting XmlElementAttribute.ElementName as shown in this answer to XML Deserialization doesn't work with abstract class, i.e.:

public class Order
{
    [XmlElement("orderSource")]
    public long OrderSource { get; set; }

    // And similarly for all remaining properties

Or

public class Order
{
    public long orderSource { get; set; }

    // And similarly for all remaining properties
dbc
  • 104,963
  • 20
  • 228
  • 340