1

I'm trying to serialize a dummy collection of orders, where each order contains a product. The collection is serializing fine, but the example product properties inside the order are being missed.

Order Collection

[XmlRoot("Orders")]
public class OrderCollection : ICollection<Order>
{
    private static List<Order> _orders;

    private List<Order> Orders
    {
        get
        {
            if(_orders == null)
            {
                _orders = new List<Order>();
            }

            return _orders;
        }
    }

    //All the ICollection functions
}

Order

public class Order
{
    [XmlElement("Id")]
    public int Id
    {
        get;
        set;
    }

    [XmlElement("Title")]
    public string Title
    {
        get;
        set;
    }

    [XmlElement("IsReserved")]
    public bool IsReserved
    {
        get;
        set;
    }

    [XmlElement("Count")]
    public int Count
    {
        get
        {
            return this.Products.Count;
        }
        set
        {

        }
    }

    // not serializing
    [XmlElement("Product")]
    public Product ProductTest
    {
        get
        {
            return new Product();
        }
    }

    // not serializing
    [XmlArray("Products")]
    public ICollection<Product> Products
    {
        get
        {
            return this._products;
        }

    }

    private List<Product> _products;

    public Order()
    {
        var rand = new Random();
        var count = rand.Next(1, 5);
        this._products = new List<Product>();

        for (int i = 0; i < count; i++)
        {
            this._products.Add(new Product());
        }
    }
}

Product

[Serializable]
public class Product 
{
    [XmlElement("Id")]
    public int Id
    {
        get;
        set;
    }

    [XmlElement("Title")]
    public string Title
    {
        get;
        set;
    }

    public Product()
    {
        var rand = new Random();
        this.Id = rand.Next(100, 9999);
        this.Title = "Product " + this.Id;
    }
}

Output

<?xml version="1.0"?>
<Orders xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Order>
    <Id>619883</Id>
    <Title>Order 619883</Title>
    <IsReserved>false</IsReserved>
    <Count>3</Count>
  </Order>
  <Order>
    <Id>961448</Id>
    <Title>Order 961448</Title>
    <IsReserved>false</IsReserved>
    <Count>3</Count>
  </Order>
  <Order>
    <Id>483677</Id>
    <Title>Order 483677</Title>
    <IsReserved>false</IsReserved>
    <Count>2</Count>
  </Order>
  <Order>
    <Id>512026</Id>
    <Title>Order 512026</Title>
    <IsReserved>false</IsReserved>
    <Count>2</Count>
  </Order>
  <Order>
    <Id>916029</Id>
    <Title>Order 916029</Title>
    <IsReserved>false</IsReserved>
    <Count>4</Count>
  </Order>
  <Order>
    <Id>109800</Id>
    <Title>Order 109800</Title>
    <IsReserved>false</IsReserved>
    <Count>4</Count>
  </Order>
</Orders>

I'm completely baffled. Deep serialization seems to be working because otherwise order wouldn't get serialized inside the OrderCollection, but then it just stops. Any advice?

4
  • I think [XmlElement("Products")] public ICollection<Product> Products should be [XmlArray("Products")] public ICollection<Product> Products msdn.microsoft.com/en-us/library/… Commented Sep 27, 2013 at 11:55
  • I already tried that, and to rule it out I added that single ProductTest property which isn't serializing either. Commented Sep 27, 2013 at 11:57
  • 1
    Try ditching all the extra code you have there. Create your classes as simple plain-old-CLR-objects. No empty setters, no get-only properties, nothing fancy and see what happens. (Also, why is the backing field private static List<Order> _orders; static?) For your XML serialization, you're best off just having a simple data model that represents your XML schema. If you want to add business/logic/validation, do it separately by converting to/from internal business classes which don't care about serialization concerns. Commented Sep 27, 2013 at 12:01
  • Have you applied the XmlRoot attribute to all your classes? [XmlRoot("Product")] Commented Sep 27, 2013 at 12:02

3 Answers 3

4

You have to change ICollection to List. An interface isn't serializeable.

[XmlArray("Products")]
public List<Product> Products
{
    get
    {
        return this._products;
    }

}

And ProductTest doesn't work because of the missing setter

Sign up to request clarification or add additional context in comments.

2 Comments

Excellent, this worked. Thanks. Question though, I'm pretty sure code analysis is going to complain about having a public list rather than an ICollection - so what's best to do there?
You can use a Collection instead of a List or disable the rule. Both are valid ways (in my opinion). If you want a Collection, you can use this to create one new Collection<Product>(this._products);
0

You can't serialize an interface..

An interface is nothing more than a description of a set of behaviors. It says nothing about the contents of an instance. In particular, although an instance of a class implementing an interface must implement all of its members, it will certainly have properties of its own which need to be serialized.

PS: copied from Serializing interfaces

Comments

0

Change into List.

Public List Products {

}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.