Newtonsoft JSON- Conversion to/from DataSet causes Decimal to become Double?

烈酒焚心 提交于 2019-12-10 15:57:46

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!