Reputation: 598
I am trying to deserialize an object of credit card bins for brand validation on a form, but can't get it done properly. Either the inside object doesn't deserialize, or the main list of brands comes null. Can anyone give me a hand or two?
My XML is like this:
<?xml version="1.0" encoding="utf-8"?>
<Brands>
<Brand type="visa">
<Bins>
<Bin enabled="true" value="123" />
<Bin enabled="true" value="456" />
<Bin enabled="true" value="789" />
</Bins>
</Brand>
<Brand type="master">
<Bins>
<Bin enabled="true" value="987" />
<Bin enabled="true" value="654" />
<Bin enabled="true" value="321" />
</Bins>
</Brand>
</Brands>
and my latest code(which brings brandsCollection null) is:
[XmlRoot("Brands")]
public class CreditCardBrand
{
[XmlArray("Brands"), XmlArrayItem("Brand")]
public CreditCardBrandCollection[] brandsCollection { get; set; }
}
public class CreditCardBrandCollection
{
[XmlElement("Bins")]
public CreditCardBrandBins[] binsCollection { get; set; }
[XmlAttribute("type")]
public CreditCardBrands brand { get; set; }
}
public class CreditCardBrandBins
{
[XmlAttribute("value")]
public string bin { get; set; }
[XmlAttribute("enabled")]
public bool enabled { get; set; }
}
I want to deserialize this xml into an array of Brands, each brand having a property name(type) and an array of bins(only the enabled ones) associated to them, so I can put it in memory at my system on startup.
Upvotes: 3
Views: 1301
Reputation: 116118
If you want to use Linq2Xml
XDocument xDoc = XDocument.Parse(xml); //or XDocument.Load(filename)
List<CreditCardBrand> brands =
xDoc.Descendants("Brand")
.Select(br => new CreditCardBrand()
{
Type = br.Attribute("type").Value,
Bins = br.Descendants("Bin")
.Select(b => new CreditCardBin(){
Enabled = (bool)b.Attribute("enabled"),
Value = b.Attribute("value").Value,
}).Where(b => b.Enabled == true)
.ToList()
})
.ToList();
--
public class CreditCardBrand
{
public string Type { get; set; }
public List<CreditCardBin> Bins { get; set; }
}
public class CreditCardBin
{
public string Value { get; set; }
public bool Enabled { get; set; }
}
Upvotes: 2
Reputation: 27962
It is actually very easy. You are just confusing — or, better to say, duplicating — the root element declaration and the way you attribute the brandsCollection
array. You have to change the declaration as follows:
[XmlRoot("Brands")]
public class CreditCardBrand
{
[XmlElement("Brand")]
public CreditCardBrandCollection[] brandsCollection { get; set; }
}
Here [XmlElement]
causes each element of the array to be represented by a single <Brand>
tag. In you original code you described an XML which would have to look like this:
<Brands>
<Brands> <!-- duplicate Brands element here -->
<Brand type="…">…</Brand>
<Brand type="…">…</Brand>
<Brand type="…">…</Brand>
…
</Brands>
</Brands>
Upvotes: 2