如何用Newtonsoft JSON.NET将double序列化为非科学计数法JSON
解决ASP.NET Core中Newtonsoft JSON.NET序列化double时的科学计数法问题
问题描述
在ASP.NET Core应用中使用Newtonsoft JSON.NET序列化double类型属性时,结果自动转为科学计数法(如{"number":1E-08}),但需要输出完整的小数格式(如{"number": 0.0000000100000000000000001234567})。已尝试设置FloatParseHandling = FloatParseHandling.Decimal及自定义转换器,问题仍存在。
相关代码如下:
- 服务配置:
builder.Services.AddControllers().AddNewtonsoftJson();
- 模型类:
public class SomeModel { public double Number { get; set; } = 0.0000000100000000000000001234567; }
- 控制器:
[ApiController] public class HomeController : ControllerBase { [HttpGet] [Route("/")] public SomeModel Index() { return new SomeModel(); } }
解决方案
1. 改用decimal类型(推荐)
double类型仅支持15-17位有效数字,你定义的数值0.0000000100000000000000001234567已超出其精度范围,实际存储时会被近似为1e-8,这是序列化出科学计数法的根本原因。
将模型属性改为decimal类型,可完整保留高精度数值:
public class SomeModel { public decimal Number { get; set; } = 0.0000000100000000000000001234567m; }
然后配置Newtonsoft JSON禁用科学计数法,搭配自定义转换器确保输出格式:
builder.Services.AddControllers().AddNewtonsoftJson(options => { options.SerializerSettings.Converters.Add(new DecimalConverter()); }); public class DecimalConverter : JsonConverter<decimal> { public override void WriteJson(JsonWriter writer, decimal value, JsonSerializer serializer) { // 指定足够多的小数位,确保完整输出 writer.WriteValue(value.ToString("0.0000000000000000000000000000")); } public override decimal ReadJson(JsonReader reader, Type objectType, decimal existingValue, bool hasExistingValue, JsonSerializer serializer) { return decimal.Parse(reader.Value.ToString()); } }
2. 保留double类型的自定义转换器方案
若无法修改属性类型,需自定义double转换器强制输出指定格式:
builder.Services.AddControllers().AddNewtonsoftJson(options => { options.SerializerSettings.Converters.Add(new DoubleConverter()); }); public class DoubleConverter : JsonConverter<double> { public override void WriteJson(JsonWriter writer, double value, JsonSerializer serializer) { // 使用不变文化确保格式一致,指定足够小数位 writer.WriteValue(value.ToString("0.0000000000000000000000000000", CultureInfo.InvariantCulture)); } public override double ReadJson(JsonReader reader, Type objectType, double existingValue, bool hasExistingValue, JsonSerializer serializer) { return double.Parse(reader.Value.ToString(), CultureInfo.InvariantCulture); } }
注意:由于double精度限制,输出数值可能与原始定义存在细微差异,这是类型特性导致的,无法完全消除。
内容的提问来源于stack exchange,提问作者TyuJas
相关产品推荐
相关产品推荐

