1、原因
原生Json反序列化时,如果多行数据第一行为int,后面多行为decimal会字段转化为int
demo文件,保存为到 E:/aa.txt:
http://cdn01.pukuimin.top/zb_users/upload/2018/jsonToDataTableDemo.txt
转为DataTable时,值自动变了:
转换为List Dictionary时,值正常。
2、解决方法
自定义DataTableConverter方法
public class CustomDataTableJsonConverter : DataTableConverter
{
/// <summary>
/// 反序列化时根据数据类型获取DataTable列类型
/// </summary>
/// <param name="tokenType">数据类型</param>
/// <returns></returns>
private static Type GetColumnDataType(JsonToken tokenType)
{
switch (tokenType)
{
// 将整数列按字符串处理,解决JavaScript中具有精度的数字
// 以字符串显示后与实际列类型冲突的问题。
case JsonToken.Integer:
return typeof(double);
case JsonToken.Float:
return typeof(double);
case JsonToken.String:
case JsonToken.Null:
case JsonToken.Undefined:
return typeof(string);
case JsonToken.Boolean:
return typeof(bool);
case JsonToken.Date:
return typeof(DateTime);
}
throw new ArgumentOutOfRangeException();
}
/// <summary>
/// 复写JSON反序列化方法。
/// </summary>
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
DataTable table;
if (reader.TokenType == JsonToken.PropertyName)
{
table = new DataTable((string)reader.Value);
reader.Read();
}
else
{
table = new DataTable();
}
reader.Read();
while (reader.TokenType == JsonToken.StartObject)
{
DataRow row = table.NewRow();
reader.Read();
while (reader.TokenType == JsonToken.PropertyName)
{
string name = (string)reader.Value;
reader.Read();
// 根据JSON数据获取Table列类型。
Type columnDataType = GetColumnDataType(reader.TokenType);
// 如果Table列集合中尚不包含此列,则将列加入到Table中。
if (!table.Columns.Contains(name))
{
table.Columns.Add(new DataColumn(name, columnDataType));
}
// 如果列类型为字符串类型。
if (table.Columns[name].DataType == typeof(string))
{
// 读取JSON数据。
string value = Convert.ToString(reader.Value);
// 如果JSON数据长度大于4,对前端转义后的尖括号进行还原。
// 解决字符在前端验证通过后,因为转义使长度变长,导致存储到数据库时长度溢出的问题。
if (value.Length >= 4)
{
value = value.Replace("<", "<").Replace(">", ">");
}
row[name] = value;
}
else
{
row[name] = reader.Value == null ? DBNull.Value : reader.Value;
}
reader.Read();
}
row.EndEdit();
table.Rows.Add(row);
reader.Read();
}
reader.Read();
return table;
}
}修改封装的数据转换方法:
/// <summary>
/// Json字符串转换为具体对象
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="jsonStr"></param>
/// <returns></returns>
public static T FromJsonTo<T>(string jsonStr)
{
if (string.IsNullOrWhiteSpace(jsonStr)) return default(T);
JsonSerializerSettings setting=new JsonSerializerSettings
{
//空值处理
NullValueHandling = NullValueHandling.Include,
MaxDepth = 10,
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
Formatting = Newtonsoft.Json.Formatting.Indented,//缩进
};
if (typeof(T) == typeof(DataTable))
{
setting.Converters.Add(new CustomDataTableJsonConverter());
}
return JsonConvert.DeserializeObject<T>(jsonStr, setting);
}修改后,转换的DataTable值正常。