06
2018
12

.Net Json转换为DataTable小数自动转成整数造成错误的问题

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("&lt;", "<").Replace("&gt;", ">");
                        }
                        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值正常。



版权声明:
作者:真爱无限 出处:http://www.pukuimin.top 本文为博主原创文章版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接.
« 上一篇下一篇 »

相关文章:

评论列表:

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。