ASP.NET WebApi 2/Core3.1大整数JSON序列化舍入问题求助
这个问题我之前也碰到过,根源在于JavaScript Number类型的精度限制——它本质是双精度浮点数,只能精确表示到2^53(也就是9007199254740992),超过这个范围的整数在转成Number类型时必然会丢失精度,出现舍入现象。你提到手动用Newtonsoft.Json序列化正常,但WebApi返回结果异常,这说明框架默认的序列化配置和你手动调用的规则不一致,下面分两种框架给出针对性解决方案:
一、ASP.NET WebApi2(.NET 4.5.2)
WebApi2默认使用Newtonsoft.Json,但可能你的项目修改了默认序列化配置,或者引入了其他Formatter导致异常。你可以显式配置Json.NET的序列化规则,确保大整数被正确处理:
打开WebApiConfig.cs,在Register方法里替换默认的Formatter配置:
public static void Register(HttpConfiguration config) { // 清除默认Formatter,避免冲突 config.Formatters.Clear(); var jsonFormatter = new JsonMediaTypeFormatter(); jsonFormatter.SerializerSettings = new JsonSerializerSettings { // 用Decimal精度处理数值,避免大整数被舍入 FloatParseHandling = FloatParseHandling.Decimal, // 保持返回结果的小驼峰命名风格 ContractResolver = new CamelCasePropertyNamesContractResolver(), Formatting = Formatting.Indented }; config.Formatters.Add(jsonFormatter); // 其他路由配置... }
配置完成后,WebApi会采用和你手动调用JsonConvert.SerializeObject一致的规则序列化,就能返回精确的大整数了。
二、ASP.NET Core 3.1
Core3.1默认使用System.Text.Json,它的默认行为在处理超大Int64时容易出现精度问题,而你手动用Newtonsoft.Json是正常的,最直接的解决方式是切换回Newtonsoft.Json:
- 先安装NuGet包:
Microsoft.AspNetCore.Mvc.NewtonsoftJson - 在
Startup.cs的ConfigureServices方法中配置:
public void ConfigureServices(IServiceCollection services) { services.AddControllers() .AddNewtonsoftJson(options => { // 配置Decimal精度处理大整数 options.SerializerSettings.FloatParseHandling = FloatParseHandling.Decimal; options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); }); // 其他服务配置... }
这个配置会让Core WebApi用Newtonsoft.Json替代默认的System.Text.Json,和你手动序列化的效果完全一致,彻底解决精度丢失问题。
如果你不想切换序列化器,也可以配置System.Text.Json的自定义转换器,但这种方式比较繁琐,而且客户端解析时还是要注意用BigInt类型处理,否则依然会有精度问题。
额外提醒
即使服务端返回了精确的大整数,客户端如果用JavaScript的Number类型去解析,还是会丢失精度。所以如果你的前端是JavaScript技术栈,建议前端用BigInt类型来解析这些大数字,或者在必要时考虑将数字序列化为字符串(虽然你说这不是理想方案,但这是前端无感知兼容的稳妥方式)。
内容的提问来源于stack exchange,提问作者thoros1179

