Getting Generic List of C# objects from XML working fine, except when I put that in a List of Objects

94 views Asked by At

This is working: (each Invoice has many LineItems)

public class Invoice
{
    public int InvoiceId { get; set; }

    public List<LineItem> LineItems { get; set; }
}

public class LineItem
{
    public int LineItemId { get; set; }
}
string strInvoice = "<Invoice>   <InvoiceId>12345</InvoiceId>   <LineItems>      <LineItem>         <LineItemId>123</LineItemId>      </LineItem>      <LineItem>         <LineItemId>456</LineItemId>      </LineItem>   </LineItems></Invoice>";

object result = new System.Xml.Serialization.XmlSerializer(typeof(Invoice)).Deserialize(new System.IO.StringReader(strInvoice));

Object gets deserialized perfectly.

But now, I try to make a List of Invoices (I now enclose the current XML string in <Invoices></Invoices>):

public class InvoiceList
{
    public List<Invoice> Invoices { get; set; }
}

string strInvoices = "<Invoices><Invoice>   <InvoiceId>12345</InvoiceId>   <LineItems>      <LineItem>         <LineItemId>123</LineItemId>      </LineItem>      <LineItem>         <LineItemId>456</LineItemId>      </LineItem>   </LineItems></Invoice></Invoices>";

object results = new System.Xml.Serialization.XmlSerializer(typeof(Invoice)).Deserialize(new System.IO.StringReader(strInvoices));

resulting in:

There is an error in XML document (1, 2).
{"<Invoices xmlns=''> was not expected."}

How can I structure my class or SQL to deserialize a list of Invoices?

Trying this - which is taken from the answer of the twitter question that was marked as duplicate, I get no results:

   string strInvoices = "<Invoices><Invoice>   <InvoiceId>12345</InvoiceId>   <LineItems>      <LineItem>         <LineItemId>123</LineItemId>      </LineItem>      <LineItem>         <LineItemId>456</LineItemId>      </LineItem>   </LineItems></Invoice></Invoices>";
    XmlRootAttribute xRoot = new XmlRootAttribute();
    xRoot.ElementName = "Invoices";
    xRoot.IsNullable = true;
    object results = new System.Xml.Serialization.XmlSerializer(typeof(Invoice),xRoot).Deserialize(new System.IO.StringReader(strInvoices));

If i do this, I get the same error:

object results = new System.Xml.Serialization.XmlSerializer(typeof(Invoice),xRoot).Deserialize(new System.IO.StringReader(strInvoices));

If I do this as comment suggested, nothing is returned:

 object results = new System.Xml.Serialization.XmlSerializer(typeof(InvoiceList),xRoot).Deserialize(new System.IO.StringReader(strInvoices));

It is thus different to the example marked as duplicate I have gone through a lot of effort to duplicate this error and make it as generic and easily readable and copy-and-pasteable into Visual Studio as possible

1

There are 1 answers

5
Charles Mager On BEST ANSWER

You're deserialising to the wrong type - you want to deserialise to InvoiceList.

You should also add some attributes to your InvoiceList class to map the element names correctly:

[XmlRoot("Invoices")]
public class InvoiceList
{
    [XmlElement("Invoice")]
    public List<Invoice> Invoices { get; set; }
}

And then you should be able to deserialise like so:

var serializer = new XmlSerializer(typeof(InvoiceList));

using (var reader = new StringReader(strInvoices))
{
    var list = (InvoiceList)serializer.Deserialize(reader);
}

See https://dotnetfiddle.net/mBtPSP for a working example.