将object转换成dyamic类型 解决long输出到浏览器过长精度丢失问题

时间:2022-10-21 14:36:47

需求:

数据库使用飘雪算法保存唯一标识  是一个18位长整形

将数据输出到浏览器时出现了精度丢失问题,这是一个重大的BUG。如果没解决好整个项目都要改一遍。

讨论有三个办法

1、把所有实体 数据模型的long值手动换成string类型。——-这是一个工作庞大且极度无聊的事情,并且给人感觉很不好

2、将模型转换成json字符串,或者对象。 ———前者是将工作丢给前端,然后前端不干了....略, ———后者需要定义一个规则,在需要更改的地方加上一个标识,json转换的时候就会将数据转换成string,比第一个方法好很多,但是加了一倍的工作量。不仅需要改现成模型,以后的模型统统需要加上表示。

3、设定一个拦截器,对象转换json对象输出前转换成动态类型然后转换成json输出。———本文章所使用的方法

 

效果图:

将object转换成dyamic类型 解决long输出到浏览器过长精度丢失问题

 

输出的两段json:

thedyamicjson

[{"ID":"1234567890123456789","Detaile":{"Name":"小熊","Age":18},"Phone":[{"PhoneNumber":"131131131111","RegisteredData":"2018-03-29T16:17:20.5334508+08:00"},{"PhoneNumber":"131131131112","RegisteredData":"2018-03-29T16:17:20.5349548+08:00"}]},{"ID":"1234567890123456777","Detaile":{"Name":"小明","Age":22},"Phone":[{"PhoneNumber":"131131132222","RegisteredData":"2018-03-29T16:17:20.5354557+08:00"},{"PhoneNumber":"131131132224","RegisteredData":"2018-03-29T16:17:20.5354557+08:00"}]}]

 

thedobjectjson

[{"ID":1234567890123456789,"Detaile":{"Name":"小熊","Age":18},"Phone":[{"PhoneNumber":131131131111,"RegisteredData":"2018-03-29T16:17:20.5334508+08:00"},{"PhoneNumber":131131131112,"RegisteredData":"2018-03-29T16:17:20.5349548+08:00"}]},{"ID":1234567890123456777,"Detaile":{"Name":"小明","Age":22},"Phone":[{"PhoneNumber":131131132222,"RegisteredData":"2018-03-29T16:17:20.5354557+08:00"},{"PhoneNumber":131131132224,"RegisteredData":"2018-03-29T16:17:20.5354557+08:00"}]}]

 

可以看到第一段的ID类型全部加上了引号

 

 

代码:

 

三个测试用的基础类

  class UserData {
            public long ID { get; set; }
           
            public UserDetaileData Detaile { get; set; }

            public List<PhoneData> Phone { get; set; }

        }
        class UserDetaileData {
            public string Name { get; set; }
            public int Age { get; set; }
        }
        class PhoneData {
            public long PhoneNumber { get; set; }

            public DateTime RegisteredData { get; set; }

        }

  

三种类型对比支持,以后只需要维护这个三个变量就行了

 string Along = "Int64";
 string AGeneric = "List`1";
 IEnumerable<string> ATypeName = new List<string>() { "String", "Int32", "Int64", "DateTime", "Decimal", "Double", "Boolean" };

  

 /// <summary>
        /// 将对象转换成动态类型变量
        /// </summary>
        /// <param name="o"></param>
        /// <returns></returns>
        private static dynamic ObjectConversionDynamic(object o)
        {
            //非空判断
            if (o==null)
            {
                return o;
            }
            //获取变量o 的type名称
            string sa = o.GetType().Name;
            //判断是否为long型(转换输出)
            if (sa == Along)
            {
                return o.ToString();
            }
            //判断是否为可输出变量(直接返回)
            if (ATypeName.Where(d => d == o.GetType().Name).ToList().Any())
            {
                return  o;
            }
            //判断是否为list (需要再次遍历,以防list中出现引用类型)
            if (sa == AGeneric)
            {
                return ListDynamic((IEnumerable)o);
            }
            //获取引用类型变量成员
            var theva = o.GetType().GetProperties();
            //初始化返回的结果值
            dynamic result = new ExpandoObject();
            //生成请求字典
            IDictionary<string, object> thekeyValuePairs = (IDictionary<string, object>)result;
            foreach (var item in theva)
            {
                //添加至字典
                thekeyValuePairs.Add(item.Name, ObjectConversionDynamic(item.GetValue(o)));
            }
            return result;
        }
        /// <summary>
        /// 将list转换成dynamic
        /// </summary>
        /// <param name="olist"></param>
        /// <returns></returns>
         static  dynamic ListDynamic(IEnumerable olist) {
            List<dynamic> theydlist = new List<dynamic>();
            foreach (var item in olist)
            {
                theydlist.Add(ObjectConversionDynamic(item));
            }
            dynamic resultlist = theydlist;
            return resultlist;
        }

 

逻辑稍有些困难,

代码粘贴可用

 

Main函数

   static void Main(string[] args)
        {
            List<UserData> user = new List<UserData>();
            UserData UserA = new UserData()
            {
                ID = 1234567890123456789,
                Detaile = new UserDetaileData()
                {
                    Age = 18,
                    Name = "小熊"
                },
                Phone = new List<PhoneData>() {
                    new PhoneData(){
                        PhoneNumber=131131131111,
                        RegisteredData=DateTime.Now,
                    },
                     new PhoneData(){
                        PhoneNumber=131131131112,
                        RegisteredData=DateTime.Now,
                    }
                }
            };
            UserData UserB = new UserData()
            {
                ID = 1234567890123456777,
                Detaile = new UserDetaileData()
                {
                    Age = 22,
                    Name = "小明"
                },
                Phone = new List<PhoneData>() {
                    new PhoneData(){
                        PhoneNumber=131131132222,
                        RegisteredData=DateTime.Now,
                    },
                     new PhoneData(){
                        PhoneNumber=131131132224,
                        RegisteredData=DateTime.Now,
                    }
                }
            };
            user.Add(UserA);
            user.Add(UserB);
            dynamic thedynamic = ObjectConversionDynamic(user);
            string thedyamicjson = JsonConvert.SerializeObject(thedynamic);
            string thedobjectjson = JsonConvert.SerializeObject(user);
           
            Console.WriteLine(thedyamicjson);
            Console.Read();
}

 

 

至于以后还有有什么变更之类的就不管了,反正现在是可用。

埋自己的雷,让别人拆去吧!