Newtonsoft JSON-转换到DataSet或从DataSet转换会导致Decimal变为Double?

我正在使用Newtonsoft JSON使用下面的代码将DataSet序列化为二进制JSON。 反序列化回DataSet时,字段类型从Decimal变为Double? 有谁知道出了什么问题?

示例代码:

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(); } ///  /// Utility function to create an optimized Binary JSON version of a DataSet ///  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(); } } } ///  /// Utility function to deserialize an optimized Binary JSON serialized DataSet ///  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(reader); } } } 

修复此设置的简单方法FloatParseHandling = FloatParseHandling.Decimal

示例

  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(json, settings); // actual.Value.GetType() == 'Decimal' 

我怀疑它与DataSetDataTable的标准(XML)序列化有关。

如果将示例中的DataSet写入文件,则会看到未提供有关DataTable架构的信息。 这可以在将XML文件读回表中时确定。

写入文件的示例中的数据给出了以下结果:

   1.23345   

当读取带有DataTableDataSet ,您无法更改列的类型(在我的测试用例中,当进入/来自XML时,类型是string )但是您可以.Clone() DataTable并移动/转换数据:

 var clonedTable = ds.Tables[0].Clone(); clonedTable.Columns[0].DataType = typeof(decimal); foreach (DataRow row in dt.Tables[0].Rows) { clonedTable.ImportRow(row); }