Web API 2如何处理格式错误的无效API请求并返回友好响应?
解决Web API 2格式错误请求的友好响应问题
当你的请求存在JSON语法错误(比如你例子里Domains后面少了冒号)时,Web API默认会抛出未处理的异常,返回500服务器错误,这确实不够友好。下面是几个关键步骤来修复这个问题,让API返回清晰的错误提示:
1. 捕获JSON格式解析错误
Web API在解析无效JSON时会触发JsonReaderException,我们可以通过自定义ExceptionFilterAttribute来捕获这类异常,返回标准化的错误响应:
public class JsonFormatExceptionFilter : ExceptionFilterAttribute { public override void OnException(HttpActionExecutedContext context) { if (context.Exception is JsonReaderException jsonEx) { var errorResponse = new HttpResponseMessage(HttpStatusCode.BadRequest) { Content = new StringContent($"JSON格式错误:{jsonEx.Message}", Encoding.UTF8, "application/json"), ReasonPhrase = "Invalid JSON Format" }; context.Response = errorResponse; } } }
然后在WebApiConfig.cs中注册这个过滤器:
public static class WebApiConfig { public static void Register(HttpConfiguration config) { // 注册JSON格式异常过滤器 config.Filters.Add(new JsonFormatExceptionFilter()); // 其他路由、序列化等配置... } }
2. 完善模型验证的错误响应
你已经实现了基于代码的验证,但还要确保Web API能统一返回模型状态的错误。可以添加一个ActionFilterAttribute来处理模型验证失败的情况:
public class InvalidModelStateFilter : ActionFilterAttribute { public override void OnActionExecuting(HttpActionContext context) { if (!context.ModelState.IsValid) { var errors = context.ModelState .Where(kv => kv.Value.Errors.Any()) .ToDictionary( kv => kv.Key, kv => kv.Value.Errors.Select(e => e.ErrorMessage).ToArray() ); var errorResponse = new HttpResponseMessage(HttpStatusCode.BadRequest) { Content = new StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(new { Message = "请求参数验证失败", Errors = errors }), Encoding.UTF8, "application/json") }; context.Response = errorResponse; } } }
同样在WebApiConfig中注册:
config.Filters.Add(new InvalidModelStateFilter());
3. 关闭默认的详细错误信息(生产环境)
为了避免泄露服务器内部敏感信息,在生产环境中要关闭Web API的详细错误输出:
// 在WebApiConfig里添加 config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Never;
4. 测试效果
现在当你提交有JSON语法错误的请求时,API会返回400 Bad Request,响应内容类似:
{ "Message": "JSON格式错误:Unexpected character encountered while parsing value: U. Path 'Domains', line 1, position 45." }
而如果是参数验证失败(比如Entities为空数组、UpdatedWithinMinutes为负数),会返回包含具体错误字段的响应,帮助用户快速定位问题。
内容的提问来源于stack exchange,提问作者user9393635
相关产品推荐
相关产品推荐

