.NET Web API:如何阻止含逗号的decimal请求参数并抛出格式错误
.NET Web API 阻止带逗号的Decimal值输入解决方案
方案一:全局配置JSON解析规则(推荐)
直接在项目启动时配置JSON序列化选项,强制使用不变文化解析数字,只认点号作为小数点,遇到逗号直接报错。
在Program.cs里添加配置:
builder.Services.AddControllers() .AddJsonOptions(options => { // 严格模式,非标准数字格式直接报错 options.JsonSerializerOptions.NumberHandling = JsonNumberHandling.Strict; // 使用不变文化,强制点号为小数点分隔符 options.JsonSerializerOptions.Culture = CultureInfo.InvariantCulture; });
配置后,客户端发送"DecimalValue": "5,1"这类请求时,Web API会直接返回400 Bad Request,提示格式无效,不会偷偷转成51。
方案二:自定义字段验证属性
如果只需要针对个别decimal字段做限制,可以写一个自定义验证属性,给目标字段加上即可。
先定义验证属性:
public class ValidDecimalFormatAttribute : ValidationAttribute { protected override ValidationResult IsValid(object value, ValidationContext validationContext) { if (value == null) return ValidationResult.Success; // 如果是字符串类型(客户端可能传字符串格式的数字) if (value is string strValue) { // 检查是否含逗号,直接拦截 if (strValue.Contains(',')) return new ValidationResult("Decimal值格式错误,不能用逗号做分隔符"); // 再用不变文化验证是否是有效decimal if (!decimal.TryParse(strValue, NumberStyles.Number, CultureInfo.InvariantCulture, out _)) return new ValidationResult("请输入有效的Decimal值"); } return ValidationResult.Success; } }
然后给TestRequest的字段加上这个属性:
public record TestRequest { [ValidDecimalFormat] public decimal DecimalValue { get; set; } }
这样客户端传带逗号的值时,模型验证会失败,返回400错误和自定义提示信息。
方案三:自定义JSON转换器
如果需要更精细的解析控制,可以写一个专属的JSON转换器,在解析阶段直接拦截带逗号的输入。
定义转换器:
public class StrictDecimalConverter : JsonConverter<decimal> { public override decimal Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { if (reader.TokenType == JsonTokenType.String) { var str = reader.GetString(); // 发现逗号直接抛异常 if (str.Contains(',')) throw new JsonException("Decimal值格式无效,禁止使用逗号作为分隔符"); // 用不变文化解析,确保格式正确 if (!decimal.TryParse(str, NumberStyles.Number, CultureInfo.InvariantCulture, out var result)) throw new JsonException("无法解析有效的Decimal值"); return result; } else if (reader.TokenType == JsonTokenType.Number) { return reader.GetDecimal(); } throw new JsonException("输入的不是有效的Decimal值"); } public override void Write(Utf8JsonWriter writer, decimal value, JsonSerializerOptions options) { writer.WriteNumberValue(value); } }
注册转换器(全局生效):
builder.Services.AddControllers() .AddJsonOptions(options => { options.JsonSerializerOptions.Converters.Add(new StrictDecimalConverter()); });
或者只给单个字段用:
public record TestRequest { [JsonConverter(typeof(StrictDecimalConverter))] public decimal DecimalValue { get; set; } }
这种方式会在JSON解析的第一步就抛出错误,直接返回400响应。
内容的提问来源于stack exchange,提问作者godot
相关产品推荐
相关产品推荐

