Web API返回十进制值丢失小数位,如何输出.00格式?
解决Web API返回Decimal时自动省略末尾零的问题
嘿,这个问题我之前也碰到过!核心原因是JSON序列化器默认会优化decimal类型的输出,把末尾的零给省略了。要实现你想要的效果——不管小数部分是不是零都保留两位,同时把超过两位的小数舍入为两位格式——得调整序列化的配置,下面分两种常用的Web API序列化场景给你具体方案:
场景1:使用Newtonsoft.Json(ASP.NET MVC/旧版ASP.NET Core)
如果你的项目用的是Newtonsoft.Json(也就是Json.NET),可以通过自定义转换器来强制格式化:
方案一:给单个属性添加转换器
先给返回模型里的decimal属性加上自定义转换器注解:
public class ApiResponse { // 替换成你实际的属性名和字段名 [JsonProperty(PropertyName = "decimalValue")] [JsonConverter(typeof(TwoDecimalPlaceConverter))] public decimal DecimalValue { get; set; } }
然后实现这个自定义转换器,处理舍入和格式化:
public class TwoDecimalPlaceConverter : JsonConverter<decimal> { // 反序列化逻辑(如果需要接收该类型参数的话) public override decimal ReadJson(JsonReader reader, Type objectType, decimal existingValue, bool hasExistingValue, JsonSerializer serializer) { return decimal.TryParse(reader.Value?.ToString(), out var result) ? result : existingValue; } // 序列化逻辑:先舍入到两位小数,再格式化为带两位小数的字符串 public override void WriteJson(JsonWriter writer, decimal value, JsonSerializer serializer) { var roundedValue = Math.Round(value, 2, MidpointRounding.AwayFromZero); writer.WriteValue(roundedValue.ToString("F2")); } }
方案二:全局配置所有Decimal类型
如果希望所有返回的decimal都遵循这个规则,可以在Startup.cs里全局添加转换器:
services.AddControllers() .AddNewtonsoftJson(options => { options.SerializerSettings.Converters.Add(new TwoDecimalPlaceConverter()); });
场景2:使用System.Text.Json(新版ASP.NET Core)
如果你的项目用的是.NET Core 3.0+默认的System.Text.Json,同样可以通过自定义转换器实现:
方案一:单个属性配置
给模型属性添加注解:
public class ApiResponse { [JsonPropertyName("decimalValue")] [JsonConverter(typeof(CustomTwoDecimalConverter))] public decimal DecimalValue { get; set; } }
实现自定义转换器:
public class CustomTwoDecimalConverter : JsonConverter<decimal> { public override decimal Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { return decimal.TryParse(reader.GetString(), out var result) ? result : default; } public override void Write(Utf8JsonWriter writer, decimal value, JsonSerializerOptions options) { var roundedValue = Math.Round(value, 2, MidpointRounding.AwayFromZero); writer.WriteStringValue(roundedValue.ToString("F2")); } }
方案二:全局配置
在Program.cs(或Startup.cs)里全局配置所有decimal的序列化规则:
builder.Services.AddControllers() .AddJsonOptions(options => { options.JsonSerializerOptions.Converters.Add(new CustomTwoDecimalConverter()); });
关键说明
ToString("F2")是核心:它会强制输出两位小数,比如52会变成"52.00",52.126会被Math.Round处理为52.13(取决于你选的舍入规则)。- 舍入规则:
MidpointRounding.AwayFromZero是四舍五入的常规规则,如果你需要其他舍入方式,可以调整这个参数。
内容的提问来源于stack exchange,提问作者C.Das
相关产品推荐
相关产品推荐

