如何在WebAPI中保留驼峰式序列化同时禁用科学计数法?
解决WebAPI驼峰序列化同时禁用decimal科学计数法的问题
这个问题我之前也碰到过,核心原因是当你关闭UseDataContractJsonSerializer后,WebAPI会使用Json.NET(Newtonsoft.Json)来处理JSON序列化,而Json.NET对于数值过大或过小的decimal类型,默认会采用科学计数法输出。要在保留驼峰命名的同时解决这个问题,只需要给Json.NET添加一个自定义的decimal转换器即可,不用改动你已经配置好的驼峰规则。
具体步骤:
定义自定义Decimal转换器
创建一个继承自JsonConverter的类,专门处理decimal类型的序列化和反序列化,强制输出为常规数字格式:using Newtonsoft.Json; using System; using System.Globalization; public class DecimalConverter : JsonConverter { // 判断是否能转换目标类型 public override bool CanConvert(Type objectType) { return objectType == typeof(decimal) || objectType == typeof(decimal?); } // 反序列化逻辑(把JSON值转成decimal) public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { if (reader.TokenType == JsonToken.String) { if (decimal.TryParse(reader.Value.ToString(), out decimal result)) { return result; } } else if (reader.TokenType == JsonToken.Float || reader.TokenType == JsonToken.Integer) { return Convert.ToDecimal(reader.Value); } return existingValue ?? default(decimal); } // 序列化逻辑(把decimal转成常规格式的字符串输出) public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { if (value is decimal decimalValue) { // 使用InvariantCulture避免区域格式问题,确保输出统一的数字格式 writer.WriteRawValue(decimalValue.ToString(CultureInfo.InvariantCulture)); } else { writer.WriteNull(); } } }在Global.asax中添加转换器配置
在你原来的驼峰序列化配置代码后面,加上这个转换器的注册:protected void Application_Start() { // 原有的驼峰序列化配置 HttpConfiguration config = GlobalConfiguration.Configuration; config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); config.Formatters.JsonFormatter.UseDataContractJsonSerializer = false; // 添加自定义decimal转换器,禁用科学计数法 config.Formatters.JsonFormatter.SerializerSettings.Converters.Add(new DecimalConverter()); }
说明:
- 这个转换器会强制所有
decimal(包括可空的decimal?)类型以常规数字格式输出,不会触发科学计数法。 - 使用
CultureInfo.InvariantCulture是为了避免不同区域设置下的格式差异(比如有些地区用逗号做小数点分隔符),保证输出的JSON数值格式统一。 - 反序列化逻辑也做了兼容,不管前端传的是字符串还是数字格式的decimal,都能正确解析。
这样配置后,既保留了驼峰式的JSON字段命名,又解决了大decimal值被序列化为科学计数法的问题。
内容的提问来源于stack exchange,提问作者M F
相关产品推荐
相关产品推荐

