.NET Core Web API整数溢出输入的正确处理方式问询
问题分析与解决方案
是否需要处理?
需要。虽然前端有表单验证,但用户可能绕过前端直接调用API(比如用Postman、curl),此时后端返回的错误响应里同时出现「模型必填」和「属性类型转换失败」两个错误,会让调用者困惑——明明已经传了模型,却提示必填。优化错误响应能提升API的可用性和友好性。
处理方式
1. 调整属性类型,让反序列化先成功
把FavoriteNumber的类型从int改为long(或int?),然后通过验证规则限制取值范围在int的合法区间内。这样反序列化不会失败,模型不会变为null,验证错误只会针对favoriteNumber属性。
修改后的模型代码:
using System.ComponentModel.DataAnnotations; namespace API.Models { public class FavoriteNumberInputDto { public string Name { get; set; } [Range(0, int.MaxValue, ErrorMessage = "Number must be between 0 and {1}.")] public long FavoriteNumber { get; set; } } }
此时传入超大数值,会返回清晰的属性级错误,不会出现模型必填的误导性提示。
2. 配置JSON序列化的溢出处理策略
如果不想修改属性类型,可以通过配置JSON序列化器的溢出行为,避免模型变为null。以ASP.NET Core默认的System.Text.Json为例:
在Program.cs中配置序列化选项:
builder.Services.AddControllers() .AddJsonOptions(options => { options.JsonSerializerOptions.NumberHandling = JsonNumberHandling.AllowOverflow; });
AllowOverflow会让超大整数自动截断为int的最大值(或最小值),但这种方式可能隐藏输入错误,建议结合自定义验证进一步校验取值范围。
3. 全局捕获反序列化异常,修正错误响应
通过全局异常过滤器或中间件,捕获JsonException,解析错误信息后构建更友好的响应。比如在ASP.NET Core中实现一个异常过滤器:
public class JsonDeserializationExceptionFilter : IExceptionFilter { public void OnException(ExceptionContext context) { if (context.Exception is JsonException jsonEx) { var problemDetails = new ProblemDetails { Status = StatusCodes.Status400BadRequest, Title = "Invalid input", Detail = "One or more fields have invalid values." }; // 提取出错的属性名 var propertyPathMatch = Regex.Match(jsonEx.Message, @"Path: (.*?)\|"); if (propertyPathMatch.Success) { var propertyName = propertyPathMatch.Groups[1].Value.Replace("$.", ""); problemDetails.Errors = new Dictionary<string, string[]> { { propertyName, new[] { $"The value is too large for {propertyName}." } } }; } context.Result = new ObjectResult(problemDetails); context.ExceptionHandled = true; } } }
然后注册过滤器:
builder.Services.AddControllers(options => { options.Filters.Add<JsonDeserializationExceptionFilter>(); });
这种方式能直接修正错误响应,只返回属性级的错误信息,移除误导性的模型必填提示。
内容的提问来源于stack exchange,提问作者Jeffrey
相关产品推荐
相关产品推荐

