Need a little help populating Class derived from XML

Solarion

Honorary Master
Joined
Nov 14, 2012
Messages
28,053
Reaction score
17,806
For starters I am using a sample taken from here. I am however only using the Customers for now just to wrap my head around this.


XML:
 <Customers>
    <Customer CustomerID="GREAL">
      <CompanyName>Great Lakes Food Market</CompanyName>
      <ContactName>Howard Snyder</ContactName>
      <ContactTitle>Marketing Manager</ContactTitle>
      <Phone>(503) 555-7555</Phone>
      <FullAddress>
        <Address>2732 Baker Blvd.</Address>
        <City>Eugene</City>
        <Region>OR</Region>
        <PostalCode>97403</PostalCode>
        <Country>USA</Country>
      </FullAddress>
    </Customer>
    <Customer CustomerID="HUNGC">
      <CompanyName>Hungry Coyote Import Store</CompanyName>
      <ContactName>Yoshi Latimer</ContactName>
      <ContactTitle>Sales Representative</ContactTitle>
      <Phone>(503) 555-6874</Phone>
      <Fax>(503) 555-2376</Fax>
      <FullAddress>
        <Address>City Center Plaza 516 Main St.</Address>
        <City>Elgin</City>
        <Region>OR</Region>
        <PostalCode>97827</PostalCode>
        <Country>USA</Country>
      </FullAddress>
    </Customer>
    <Customer CustomerID="LAZYK">
      <CompanyName>Lazy K Kountry Store</CompanyName>
      <ContactName>John Steel</ContactName>
      <ContactTitle>Marketing Manager</ContactTitle>
      <Phone>(509) 555-7969</Phone>
      <Fax>(509) 555-6221</Fax>
      <FullAddress>
        <Address>12 Orchestra Terrace</Address>
        <City>Walla Walla</City>
        <Region>WA</Region>
        <PostalCode>99362</PostalCode>
        <Country>USA</Country>
      </FullAddress>
    </Customer>
    <Customer CustomerID="LETSS">
      <CompanyName>Let's Stop N Shop</CompanyName>
      <ContactName>Jaime Yorres</ContactName>
      <ContactTitle>Owner</ContactTitle>
      <Phone>(415) 555-5938</Phone>
      <FullAddress>
        <Address>87 Polk St. Suite 5</Address>
        <City>San Francisco</City>
        <Region>CA</Region>
        <PostalCode>94117</PostalCode>
        <Country>USA</Country>
      </FullAddress>
    </Customer>
  </Customers>

These are the classes I get generated from the above.

C#:
    [XmlRoot(ElementName="FullAddress")]
    public class FullAddress {
        [XmlElement(ElementName="Address")]
        public string Address { get; set; }
        [XmlElement(ElementName="City")]
        public string City { get; set; }
        [XmlElement(ElementName="Region")]
        public string Region { get; set; }
        [XmlElement(ElementName="PostalCode")]
        public string PostalCode { get; set; }
        [XmlElement(ElementName="Country")]
        public string Country { get; set; }
    }

    [XmlRoot(ElementName="Customer")]
    public class Customer {
        [XmlElement(ElementName="CompanyName")]
        public string CompanyName { get; set; }
        [XmlElement(ElementName="ContactName")]
        public string ContactName { get; set; }
        [XmlElement(ElementName="ContactTitle")]
        public string ContactTitle { get; set; }
        [XmlElement(ElementName="Phone")]
        public string Phone { get; set; }
        [XmlElement(ElementName="FullAddress")]
        public FullAddress FullAddress { get; set; }
        [XmlAttribute(AttributeName="CustomerID")]
        public string CustomerID { get; set; }
        [XmlElement(ElementName="Fax")]
        public string Fax { get; set; }
    }

    [XmlRoot(ElementName="Customers")]
    public class Customers {
        [XmlElement(ElementName="Customer")]
        public List<Customer> Customer { get; set; }
    }

I just quickly put this code together just for illustrating the problem I'm getting.
This is the API code I'm using to populate the customers, address etc. But as you can see my output is not the same as you can see I'm getting a nested list inside Customer. So it's become Customers > Customer > Customer.

It has something to do with the way I'm defining or populating the customer/customer list. I'm wracking my brain with this since yesterday morning. Where am I going wrong please guys!

C#:
       public Customers Get()
        {
            FullAddress address = new FullAddress();
            address.Address = "2732 Baker Blvd";

            address.City = "Eugene";
            address.Region = "OR";
            address.PostalCode = "97403";
            address.Country = "USA";

            List<Customer> customersList = new List<Customer>()
            {
                new Customer { CompanyName = "Ocean Freight", ContactName = "12.50", ContactTitle = "Dollar",Phone="", FullAddress= address, CustomerID="GREAL", Fax="(503) 555-2376"},
                new Customer { CompanyName = "Ocean Freight", ContactName = "12.50", ContactTitle = "Dollar",Phone="", FullAddress= address, CustomerID="GREAL", Fax="(503) 555-2376"},
                new Customer { CompanyName = "Ocean Freight", ContactName = "12.50", ContactTitle = "Dollar",Phone="", FullAddress= address, CustomerID="GREAL", Fax="(503) 555-2376"},
            };

            Customers customerList = new Customers();
            customerList.Customer = customersList;

            return customerList;

        }

XML:
<?xml version="1.0" encoding="UTF-8"?>
<Customers xmlns="http://schemas.datacontract.org/2004/07/WebApplication1.Controllers" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
   <Customer>
      <Customer>
         <CompanyName>Ocean Freight</CompanyName>
         <ContactName>12.50</ContactName>
         <ContactTitle>Dollar</ContactTitle>
         <CustomerID>GREAL</CustomerID>
         <Fax>(503) 555-2376</Fax>
         <FullAddress>
            <Address>2732 Baker Blvd</Address>
            <City>Eugene</City>
            <Country>USA</Country>
            <PostalCode>97403</PostalCode>
            <Region>OR</Region>
         </FullAddress>
         <Phone />
      </Customer>
      <Customer>
         <CompanyName>Ocean Freight</CompanyName>
         <ContactName>12.50</ContactName>
         <ContactTitle>Dollar</ContactTitle>
         <CustomerID>GREAL</CustomerID>
         <Fax>(503) 555-2376</Fax>
         <FullAddress>
            <Address>2732 Baker Blvd</Address>
            <City>Eugene</City>
            <Country>USA</Country>
            <PostalCode>97403</PostalCode>
            <Region>OR</Region>
         </FullAddress>
         <Phone />
      </Customer>
      <Customer>
         <CompanyName>Ocean Freight</CompanyName>
         <ContactName>12.50</ContactName>
         <ContactTitle>Dollar</ContactTitle>
         <CustomerID>GREAL</CustomerID>
         <Fax>(503) 555-2376</Fax>
         <FullAddress>
            <Address>2732 Baker Blvd</Address>
            <City>Eugene</City>
            <Country>USA</Country>
            <PostalCode>97403</PostalCode>
            <Region>OR</Region>
         </FullAddress>
         <Phone />
      </Customer>
   </Customer>
</Customers>
 
Last edited:
How it looks as JSON. Definitely an empty list there.

json.jpg
 
Last edited:
Change it as follows; should be obvious now
C#:
    [XmlRoot(ElementName="Customers")]
    public class Customers {
        [XmlElement(ElementName="BananaCustomer")]
        public List<Customer> Customer { get; set; }
    }
 
Definitely not coming right here. Still getting a list within a list.

C#:
        public Root Get()
        {
            FullAddress address = new FullAddress();
            address.Address = "2732 Baker Blvd";

            address.City = "Eugene";
            address.Region = "OR";
            address.PostalCode = "97403";
            address.Country = "USA";

            List<Customer> customerList = new List<Customer>()
            {
                new Customer { CompanyName = "Ocean Freight1", ContactName = "12.50", ContactTitle = "Dollar",Phone="", FullAddress= address, CustomerID="GREAL", Fax="(503) 555-2376"},
                new Customer { CompanyName = "Ocean Freight2", ContactName = "12.50", ContactTitle = "Dollar",Phone="", FullAddress= address, CustomerID="GREAL", Fax="(503) 555-2376"},
                new Customer { CompanyName = "Ocean Freight3", ContactName = "12.50", ContactTitle = "Dollar",Phone="", FullAddress= address, CustomerID="GREAL", Fax="(503) 555-2376"},
            };

            Customers customers = new Customers
            {
                Customer = customerList.ToList()
            };


            Root root = new Root
            {
                Customers = customers
            };

            return root;
        }

Screenshot-1.jpg
 
Last edited:
This is the class. I'm known to over-complicate things it's my curse. If anybody can point me to a different or easier way of doing all this I'd appreciate your feedback. Can't imagine doing this kind of thing for every API service.

C#:
    [XmlRoot(ElementName = "FullAddress")]
    public class FullAddress
    {
        [XmlElement(ElementName = "Address")]
        public string Address { get; set; }
        [XmlElement(ElementName = "City")]
        public string City { get; set; }
        [XmlElement(ElementName = "Region")]
        public string Region { get; set; }
        [XmlElement(ElementName = "PostalCode")]
        public string PostalCode { get; set; }
        [XmlElement(ElementName = "Country")]
        public string Country { get; set; }
    }

    [XmlRoot(ElementName = "Customer")]
    public class Customer
    {
        [XmlElement(ElementName = "CompanyName")]
        public string CompanyName { get; set; }
        [XmlElement(ElementName = "ContactName")]
        public string ContactName { get; set; }
        [XmlElement(ElementName = "ContactTitle")]
        public string ContactTitle { get; set; }
        [XmlElement(ElementName = "Phone")]
        public string Phone { get; set; }
        [XmlElement(ElementName = "FullAddress")]
        public FullAddress FullAddress { get; set; }
        [XmlAttribute(AttributeName = "CustomerID")]
        public string CustomerID { get; set; }
        [XmlElement(ElementName = "Fax")]
        public string Fax { get; set; }
    }

    [XmlRoot(ElementName = "Customers")]
    public class Customers
    {
        [XmlElement(ElementName = "Customer")]
        public List<Customer> Customer { get; set; }
    }

    [XmlRoot(ElementName = "ShipInfo")]
    public class ShipInfo
    {
        [XmlElement(ElementName = "ShipVia")]
        public string ShipVia { get; set; }
        [XmlElement(ElementName = "Freight")]
        public string Freight { get; set; }
        [XmlElement(ElementName = "ShipName")]
        public string ShipName { get; set; }
        [XmlElement(ElementName = "ShipAddress")]
        public string ShipAddress { get; set; }
        [XmlElement(ElementName = "ShipCity")]
        public string ShipCity { get; set; }
        [XmlElement(ElementName = "ShipRegion")]
        public string ShipRegion { get; set; }
        [XmlElement(ElementName = "ShipPostalCode")]
        public string ShipPostalCode { get; set; }
        [XmlElement(ElementName = "ShipCountry")]
        public string ShipCountry { get; set; }
        [XmlAttribute(AttributeName = "ShippedDate")]
        public string ShippedDate { get; set; }
    }

    [XmlRoot(ElementName = "Order")]
    public class Order
    {
        [XmlElement(ElementName = "CustomerID")]
        public string CustomerID { get; set; }
        [XmlElement(ElementName = "EmployeeID")]
        public string EmployeeID { get; set; }
        [XmlElement(ElementName = "OrderDate")]
        public string OrderDate { get; set; }
        [XmlElement(ElementName = "RequiredDate")]
        public string RequiredDate { get; set; }
        [XmlElement(ElementName = "ShipInfo")]
        public ShipInfo ShipInfo { get; set; }
    }

    [XmlRoot(ElementName = "Orders")]
    public class Orders
    {
        [XmlElement(ElementName = "Order")]
        public List<Order> Order { get; set; }
    }

    [XmlRoot(ElementName = "Root")]
    public class Root
    {
        [XmlElement(ElementName = "Customers")]
        public Customers Customers { get; set; }

        [XmlElement(ElementName = "Orders")]
        public Orders Orders { get; set; }

        [XmlAttribute(AttributeName = "xmlns")]
        public string Xmlns { get; set; }
    }
 
**** bro why so complicated. Just use json instead. Much more compact and use newtonsoft to serialise and deserialise with literlly one line of code
 
**** bro why so complicated. Just use json instead. Much more compact and use newtonsoft to serialise and deserialise with literlly one line of code

Thank-you Spacerat. I knew there had to be an easier way just needed to be put in the right direction. :thumbsup::)
 
Just create a DTO class that acts as a vehicle for the data and serialise/deserialise json. Cannot be simpler

Code:
public class MyDto
{
  public string StringField {get;set;}
  public List<SomeClass> MyList {get;set;}
}

and then
MyDto dto = new MyDto(){....}
string json = JsonConvert.Serialize(dto);

MyDto deserialisedDto = JsonConvert.Deserialise<MyDto>(json);
 
Thanks a lot man. Much better!! I am across serialization in my searches but the penny didn't drop so I ignored it.
 
This is the class. I'm known to over-complicate things it's my curse. If anybody can point me to a different or easier way of doing all this I'd appreciate your feedback. Can't imagine doing this kind of thing for every API service.

C#:
...

    [XmlRoot(ElementName = "Customer")]
    public class Customer
    {
...
    }

...
        [XmlElement(ElementName = "Customer")]
        public List<Customer> Customer { get; set; }
    }
...

These above two properties have the same Xml element name; change the name of the second one:
C#:
        [XmlElement(ElementName = "BananaCustomer")]
        public List<Customer> Customer { get; set; }
    }


Alternatively avoid the unnecessary encapsulation, and rather define your root element like this instead.
C#:
   [XmlRoot(ElementName = "Root")]
    public class Root
    {
        [XmlElement(ElementName = "Customers")]
        public List<Customer> Customers { get; set; }

        [XmlElement(ElementName = "Orders")]
        public List<Order> Orders { get; set; }
...
    }
i.e. avoid these two classes:
C#:
    [XmlRoot(ElementName = "Customers")]
    public class Customers
    {
        [XmlElement(ElementName = "Customer")]
        public List<Customer> Customer { get; set; }
    }

    [XmlRoot(ElementName = "Orders")]
    public class Orders
    {
        [XmlElement(ElementName = "Order")]
        public List<Order> Order { get; set; }
    }
 
Thank-you Roi I get it, probably should rather create them myself instead of relying on visual studio to generate.
 
C# is pretty good at serislizing xml. I use it a lot when taking to older soap services. As long as the wsdl is correct, you should have no issue.
 
Top
Sign up to the MyBroadband newsletter
X