3

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.

2 Answers 2

2

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; }
}
Sign up to request clarification or add additional context in comments.

2 Comments

Actually, I just added a where clause on the second select so it brings only enabled bins. Other than that, it was right on the spot! Thanks again!
@leobelones yes, I missed (only the enabled ones)
2

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>

1 Comment

Ty for the feedback, Ondrej... I figured it would be easier to just abort this implementation and just go for the plain Linq2XML like L.B suggested.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.