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'
我怀疑它与DataSet
和DataTable
的标准(XML)序列化有关。
如果将示例中的DataSet
写入文件,则会看到未提供有关DataTable
架构的信息。 这可以在将XML文件读回表中时确定。
写入文件的示例中的数据给出了以下结果:
1.23345
当读取带有DataTable
的DataSet
,您无法更改列的类型(在我的测试用例中,当进入/来自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); }