Reputation: 629
I need to output XML via serialised objects using XSD. My code achieves this successfully, but there is one issue I need help with.
I have a class called GAD (auto generated using the XSD.exe tool from the XSD) containing a field named total with a type of decimal. In the XSD the element is defined as <xs:element name="Total" type="xs:decimal"/>
My final output is going to a third-party validation tool that requires money-style decimals such as 20.00.
My input is a DataTable. This is currently derived from a CSV file (although eventually I will be taking this directly from a database). The DataTable is populated from the CSV using OleDbDataAdapter. Currently the values such as 20.00 are stored in double type columns so the values for whole numbers are 'truncated' to 20.0, for example.
I need to go from a DataRow holding a double value of 20.0 to a decimal object field with a value of 20.00
In trying to achieve this the best I have come up with is converting the double to a string with a format such as this, and then using Math.Round to specify two decimal places when converted back to decimal. It looks like this:
string dstr = dr["Total"].ToString(); //store the data row value in a string
double d = Convert.ToDouble(dstr); //store the value in a double
dstr = d.ToString("0.00"); //convert the double to a formatted string
decimal NewDec = Math.Round(Convert.ToDecimal(dstr), 2); //decimal value trying to retain decimal places
GAD.Total = NewDec; //finally store value in my object's field
But it doesn't work. What is stored in GAD.Total is just 20.
I was playing around trying to figure this behaviour out and I don't understand this at all. If I write out the decimal value using the console it displays as 20.00 but hovering over the value shows it is stored as 20:
class Program
{
static void Main(string[] args)
{
double d = 20.0;
Console.Write("Cast double as string with format:");
Console.WriteLine(d.ToString("0.00"));
string dstr = d.ToString("0.00");
Console.Write("Cast as string then back to decimal rounded 2 places:");
Console.WriteLine(Math.Round(Convert.ToDecimal(dstr),2));
d = 20;
dstr = d.ToString("0.00");
Console.WriteLine(Math.Round(Convert.ToDecimal(dstr), 2));
decimal NewDec = Math.Round(Convert.ToDecimal(dstr), 2);
Console.Write("Stored in a decimal: ");
Console.WriteLine(NewDec);
Console.Read();
}
}
So, I have two questions:
Thank you for your attention and I would be grateful for any help you can offer me.
Upvotes: 0
Views: 3622
Reputation: 629
I still don't know the answer to question 1 but I have solved question 2.
As per this link http://social.msdn.microsoft.com/Forums/en-US/csharplanguage/thread/d7582772-ab2c-4f05-9ba3-c96728dfbe82 I changed the definition of my class GAD.
[XmlIgnore]
public decimal Total
{
get
{
return this.totalField;
}
set
{
this.totalField = value;
}
}
[XmlElement("Total")]
public string TotalString
{
get
{
return Total.ToString("F2");
}
set
{
decimal total = 0;
if (Decimal.TryParse(value, out total))
Total = total;
}
}
Now, when I initialise the object field from my data table I can simply use GAD.Total = Convert.ToDecimal(dr["Total"]);
and the serialized output in XML always returns the numeric value with two decimal places, like so: <Total>30.00</Total>
Upvotes: 1