问题
I'm using Newtonsoft JSON to serialize a DataSet to binary JSON using the code below. When de-serializing back to a DataSet, the field type changes from a Decimal to a Double? Does anybody know what's going wrong?
Sample code:
static void Main(string[] args)
{
var ds = new DataSet();
var dt = ds.Tables.Add();
dt.Columns.Add("Test", typeof(Decimal));
dt.Rows.Add(new object[] { 1.23345M });
var data = DataSetToBinJSON(ds);
var ds2 = BinJSONToDataSet(data);
Console.WriteLine((ds2.Tables[0].Columns[0].DataType == typeof(Decimal)) ? "Passed" : string.Format("Failed- {0}", ds2.Tables[0].Columns[0].DataType));
Console.ReadLine();
}
/// <summary>
/// Utility function to create an optimized Binary JSON version of a DataSet
/// </summary>
public static byte[] DataSetToBinJSON(DataSet dataSet)
{
if (dataSet == null || dataSet.Tables == null || dataSet.Tables.Count == 0)
{
return null;
}
using (var ms = new MemoryStream())
{
using (var writer = new BsonWriter(ms))
{
var serializer = new JsonSerializer();
serializer.Serialize(writer, dataSet);
return ms.ToArray();
}
}
}
/// <summary>
/// Utility function to deserialize an optimized Binary JSON serialized DataSet
/// </summary>
public static DataSet BinJSONToDataSet(byte[] dataBytes)
{
if (dataBytes.Length == 0)
{
return null;
}
using (var ms = new MemoryStream(dataBytes))
{
using (var reader = new BsonReader(ms))
{
var serializer = new JsonSerializer();
return serializer.Deserialize<DataSet>(reader);
}
}
}
回答1:
Easy way to fix this set FloatParseHandling = FloatParseHandling.Decimal
Example:
public class Foo
{
public object Value { get; set; }
}
Foo original = new Foo
{
Value = 1.23m
};
string json = JsonConvert.SerializeObject(original);
var settings = new JsonSerializerSettings
{
FloatParseHandling = FloatParseHandling.Decimal //hint
};
Foo actual = JsonConvert.DeserializeObject<Foo>(json, settings);
// actual.Value.GetType() == 'Decimal'
回答2:
I suspect it has something to do with the standard (XML) serialization of DataSet
and DataTable
.
If you write DataSet
from the example to a file you'll see that information about the DataTable
schema isn't provided. This can be determined when reading the XML file back into a table.
The data from your example written to a file gives this result:
<NewDataSet>
<Table1>
<Test>1.23345</Test>
</Table1>
</NewDataSet>
When the DataSet
with the DataTable
has been read you can't change the type of the column (in my test case when going to/from XML the type is string
) but you can .Clone()
the DataTable
and move/convert the data:
var clonedTable = ds.Tables[0].Clone();
clonedTable.Columns[0].DataType = typeof(decimal);
foreach (DataRow row in dt.Tables[0].Rows) {
clonedTable.ImportRow(row);
}
来源:https://stackoverflow.com/questions/17597594/newtonsoft-json-conversion-to-from-dataset-causes-decimal-to-become-double