Json.NET特殊处理64位长整型数据

  

很多ASP.NET项目,尤其是使用了Ajax的项目,常常需要返回JSON格式的数据,网框架从3.5版本开始提供了JSON的序列化和反序列化工具,不过个人感觉不太好,用后来找了第三方的Newtonsoft.Json来用。再后来,在MVC4中,微软已经默认使用Json.NET (Newtonsoft。Json)来处理Json数据了。


JavaScript数值精度是32位,如果整数数度超过32位,就会被当作浮点数处理。换句话说,如果从服务端生成的Json,某个值是64位整数,传到前端JavaScript,再传回服务端,不做任何运算,都可能出现失真。做个实验:


比;var=123456789012345678   比;console.log(一个);   123456789012345680


很要命的一点是,数据库设计中常常会用长整型数字(64位)整数来作为主键,是一个非常重要而且不能有偏差的数据,比如,一个模型:


//c#匿名对象
  新{
  id: 123456789012345678 l,
  名称:“詹姆斯”
  };


转换成JSON输出到前端是:


 {" id ": 123456789012345678,“名字”:“詹姆斯”}


通过Ajax取得的对象输出就有点不妙了


.getJSON美元(“/api/测试”).done(函数(乔){   console.log(乔);   });   {//对象id: 123456789012345680,名字:“詹姆斯”}


显然,这个对象修改数值之后再传回服务器,就会找不到主键,或者更新成错误的数据,造成一个不易发现的巨大错误。


解决办法当然是有的,JavaScript处理字符串的能力非常强,完全可以把服务器端的64位整数处理成字符串类型。不过Json。净默认是把长处理成数字类型的,如果要处理成字符串类型,需要自定义一个JsonConverter。


考虑到用十六进制表示的整数看起来比较整齐,所以定义一个HexLongConverter来转换长/ulong型数据与16进制表示的字符串。


公共类HexLongConverter: JsonConverter
  {
  公共覆盖空白WriteJson (JsonWriter作家,对象的价值,JsonSerializer序列化器)
  {//由于CanConvert过滤,数据类型只可能是长或ulong//统一转换成长类型处理
  ulong v=值?(长)(ulong)价值:(长)值;
  writer.WriteValue (v.ToString(“乘16”));
  }
  公共覆盖对象ReadJson (objectType JsonReader读者,类型、对象existingValue JsonSerializer序列化器)
  {//取得读到的十六进制字符串
  十六进制字符串=读者。值作为字符串;//调用ToInt64扩展将字符串转换成型//ToInt64扩展方法后附
  长v=hex.ToInt64 (NumberStyles。HexNumber 0 l);//将v转换成实际需要的类型ulong或长(不转换)
  返回typeof (ulong)==objectType吗?(对象)(ulong) v:;
  }
  公共覆盖bool CanConvert objectType(类型)
  {//只处理长和ulong两种类型的数据
  开关(objectType.FullName)
  {
  例“System.Int64”:
  例“System.UInt64”:
  返回true;
  默认值:
  返回错误;
  }
  }
  }


上面的代码用到了一个字符串的扩展方法ToInt32:


 StringExtention公共静态类
  {
  公共静态int ToInt32(我这个字符串,NumberStyles风格,
  int defaultValue)
  {
  int ?值=https://www.yisu.com/zixun/me.ToInt32(风格);
  返回值==零?defaultValue: value.Value;
  }
  }


在序列化或反序列化模型的时候,只需要加入HexLongConverter对象作为参数即可:


//序列化
  json=JsonConvert字符串。SerializeObject(模型、新HexLongConverter ());//反序列化
  SomeModal模型=JsonConvert.DeserializeObject (json,新的HexLongConverter)); 



<人力资源/>

相关链接:


(json。净)

<李> http://json.codeplex.com/

<李> http://james.newtonking.com/json



Json.NET特殊处理64位长整型数据