我们用Newtonsoft.Json.Linq.JObject.GetValue("[key]").ToObject方法把一个JObject对象中的某个节点转换成DataTable格式的数据很方便。一直这样用也没出什么问题。但是最近发现在某些情况下,这种数据转换其实是有一定的问题甚至报错。场景如下:
1. 当数据源类似如下时。当把Data节点的数据转换成DataTable格式时,会默认abc字段为整型,导致在对第二条数据做转换时,50.11会丢失精度,变成整型50
"{\"Data\":[{\"abc\":50},{\"abc\":50.01}]}"
2. 当数据源类似如下时。就会导致第二条数据在转化成INT类型时出错。
"{\"Data\":[{\"abc\":50},{\"abc\":\"xyz\"}]}"
这个就需要用到ToObject的JsonSerializer参数了。通过重写serializer方法,来具体指定某一列的数据类型,从而达到效果。
public class CustomDataTableConverter : DataTableConverter
{
private static void CreateRow(JsonReader reader, DataTable dt)
{
DataRow row = dt.NewRow();
reader.Read();
while(reader.TokenType == JsonToken.PropertyName)
{
string columnName = (string)reader.Value;
reader.Read();
DataColumn column = dt.Columns[columnName];
if(column == null)
{
Type columnDataType = GetColumnDataType(reader);
column = new DataColumn(columnName, columnDataType);
dt.Columns.Add(column);
}
if(column.DataType == typeof(DataTable))
{
if(reader.TokenType == JsonToken.StartArray)
{
reader.Read();
}
DataTable table = new DataTable();
while(reader.TokenType != JsonToken.EndArray)
{
CreateRow(reader, table);
reader.Read();
}
row[columnName] = table;
}
else if(column.DataType.IsArray && (column.DataType != typeof(byte[])))
{
if(reader.TokenType == JsonToken.StartArray)
{
reader.Read();
}
List
调用方法
JsonSerializer serializer = new JsonSerializer();
serializer.Converts.Add(new CustomDataTableConverter());
JObject.GetValue("[Key]").ToObject(serializer);
这样就能相对正确地把数据转成DataTable。