在ASP.NET Core服务中自定义BadRequest响应的验证错误消息
在ASP.NET Core服务中自定义BadRequest响应的验证错误消息
嘿,我看你现在的场景是用了自定义的MyId类型作为Header参数,还写了对应的TypeConverter,但默认的验证错误消息肯定太生硬了,比如类似“无法将字符串转换为MyId类型”这种,用户看了一脸懵对吧?我来给你捋捋怎么改成友好的自定义错误响应。
首先,咱们得先把MyIdTypeConverter里的转换逻辑补全,并且在转换失败时抛出明确的业务相关异常,这样后面才能拿到咱们想要的错误信息。比如假设你的MyId格式要求是X:Y:Z这种冒号分隔的三段式字符串,那ConvertFrom方法可以这么写:
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) { var inputStr = value as string; if (string.IsNullOrWhiteSpace(inputStr)) { throw new FormatException("MyId请求头不能为空"); } var parts = inputStr.Split(':'); if (parts.Length != 3) { throw new FormatException("MyId格式不正确,必须符合X:Y:Z的三段式冒号分隔格式"); } if (parts.Any(string.IsNullOrWhiteSpace)) { throw new FormatException("MyId的X、Y、Z三个部分均不能为空字符串"); } return new MyId { X = parts[0], Y = parts[1], Z = parts[2] }; }
接下来,默认的ApiController特性会自动捕获模型绑定的错误并返回BadRequest,但它不会自动提取咱们抛出的异常消息,所以我们需要全局配置一下,替换默认的错误响应生成逻辑。在你的Program.cs(.NET 6+)或者Startup.cs的ConfigureServices方法里加这段配置:
builder.Services.Configure<ApiBehaviorOptions>(options => { options.InvalidModelStateResponseFactory = context => { // 把所有验证错误整理成更友好的键值对格式 var validationErrors = context.ModelState .Where(entry => entry.Value.Errors.Any()) .ToDictionary( entry => entry.Key, entry => entry.Value.Errors.Select(error => // 优先用异常的自定义消息,没有的话再用系统默认错误信息 string.IsNullOrEmpty(error.ErrorMessage) && error.Exception != null ? error.Exception.Message : error.ErrorMessage ).ToArray() ); // 自定义响应的结构,你可以根据业务需求随便调整,比如加错误码、提示语之类的 var customResponse = new { Code = "INVALID_PARAMETER", Message = "请求参数验证失败,请检查后重试", ErrorDetails = validationErrors }; return new BadRequestObjectResult(customResponse); }; });
这样一来,当Header里的MyId格式不对时,返回的BadRequest响应就是咱们自定义的结构和消息了,比如:
{ "Code": "INVALID_PARAMETER", "Message": "请求参数验证失败,请检查后重试", "ErrorDetails": { "myId": [ "MyId格式不正确,必须符合X:Y:Z的三段式冒号分隔格式" ] } }
另外再提两个小细节:
- 确保你的控制器上
[ApiController]特性是启用的,这个特性是自动触发模型验证并返回BadRequest的核心 - 如果你想针对不同的错误场景做更细的区分,还可以在
InvalidModelStateResponseFactory里根据参数类型或者异常类型来定制不同的响应内容,比如专门给MyId的错误加个特殊的业务提示
备注:内容来源于stack exchange,提问作者gehho
相关产品推荐
相关产品推荐

