I am attempting to implement a portion of the Ally Accounts API in C#. I've run into a problem with a particular endpoint.
I want to get a specific account's balance:
[XmlRoot("accountbalance")]
public class SummaryAccountBalance : Balance
{
[XmlElement("buyingpower")]
public BuyingPower BuyingPower { get; set; }
[XmlElement("fedcall")]
public decimal FedCall { get; set; }
[XmlElement("housecall")]
public decimal HouseCall { get; set; }
[XmlElement("money")]
public AccountMoney Money { get; set; }
[XmlElement("securities")]
public Securities Securities { get; set; }
}
Where Balance
is a simple abstract class:
public abstract class Balance
{
[XmlElement("account")]
public int Account { get; set; }
[XmlElement("accountvalue")]
public decimal AccountValue { get; set; }
}
For other endpoints this works just fine and I am able to get summary account balance information using this structure, for example in this endpoint.
But the /accounts/xxxxxxx/balances.xml
doesn't want to work for me. Given this file:
<?xml version="1.0" encoding="UTF-8"?>
<response id="77cf30da:12df25c7074:-7ea6">
<accountbalance>
<account>12345678</account>
<accountvalue>67119.41</accountvalue>
<buyingpower>
<cashavailableforwithdrawal>66177.48000000001</cashavailableforwithdrawal>
<daytrading>264709.84</daytrading>
<equitypercentage>100</equitypercentage>
<options>66177.48000000001</options>
<soddaytrading>264709.84</soddaytrading>
<sodoptions>66177.48000000001</sodoptions>
<sodstock>132354.96000000002</sodstock>
<stock>132354.96000000002</stock>
</buyingpower>
<fedcall>0.0</fedcall>
<housecall>0.0</housecall>
<money>
<accruedinterest>0.0</accruedinterest>
<cash>66134.67</cash>
<cashavailable>0.0</cashavailable>
<marginbalance>0.0</marginbalance>
<mmf>0.02</mmf>
<total>66134.69</total>
<uncleareddeposits>0.0</uncleareddeposits>
<unsettledfunds>0.0</unsettledfunds>
<yield>0.0</yield>
</money>
<securities>
<longoptions>0.0</longoptions>
<longstocks>57.39</longstocks>
<options>0.0</options>
<shortoptions>0.0</shortoptions>
<shortstocks>0.0</shortstocks>
<stocks>57.39</stocks>
<total>984.72</total>
</securities>
</accountbalance>
</response>
The following code detects it is indeed a SummaryAccountBalance
but fails to populate the fields:
var serializer = new XmlSerializer(typeof(SummaryAccountBalance), new XmlRootAttribute("response"));
return (SummaryAccountBalance)serializer.Deserialize(summaryAccountBalance);
where summaryAccountBalance
is the byte stream version of the file above.
I'm not sure where I have gone wrong here and I'm pulling my hair out trying to solve it. Even stepping through the code line by line there doesn't seem to be any problems at all until this deserialization step. More to the point, this exact object is used in other endpoints and those endpoint implementations have no problem deserializing it.
What am I missing to make this work?
What am I missing to make this work?
What you are missing is that <response>
is not your SummaryAccountBalance
. It's the nested <accountbalance>
element.
You need to declare one more class to describe the whole XML:
[XmlRoot("response")]
public class SummaryAccountBalanceResponse
{
[XmlAttribute("id")]
public string Id { get; set; }
[XmlElement("accountbalance")]
public SummaryAccountBalance Balance { get; set; }
}
and deserialize into this class:
var serializer = new XmlSerializer(typeof(SummaryAccountBalanceResponse));
return ((SummaryAccountBalanceResponse)serializer.Deserialize(summaryAccountBalance)).Balance;