Web API 2路由不匹配时如何处理404?当前默认返回JSON提示
处理Web API 2中路由不匹配的404错误
嘿,我刚好之前在Web API 2里处理过一模一样的问题!默认的404返回确实有点生硬,咱们可以通过两种常用方式来定制这个路由不匹配时的404响应,下面给你详细拆解:
方案一:用自定义消息处理器拦截所有404响应
这种方式会拦截整个Web API pipeline里的所有404响应,不管是找不到控制器还是找不到具体资源,都能统一处理成你想要的格式。
首先创建一个继承自DelegatingHandler的自定义处理器:
public class NotFoundHandler : DelegatingHandler { protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { // 先让请求正常走流程 var response = await base.SendAsync(request, cancellationToken); // 判断是否是默认的404响应 if (response.StatusCode == HttpStatusCode.NotFound && response.Content is ObjectContent<HttpError>) { // 这里自定义你的404返回内容,格式随便你定 var customError = new { StatusCode = (int)HttpStatusCode.NotFound, Message = "请求的API资源不存在,请检查请求地址是否正确", RequestedUri = request.RequestUri.ToString() }; // 返回自定义的404响应 return request.CreateResponse(HttpStatusCode.NotFound, customError); } // 不是404的话就返回原响应 return response; } }
然后在你的WebApiConfig的Register方法里注册这个处理器:
public static void Register(HttpConfiguration config) { // 注册自定义404处理器 config.MessageHandlers.Add(new NotFoundHandler()); // 你的原有路由配置 config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); }
方案二:自定义控制器选择器,精准处理“找不到控制器”的情况
如果你只想针对控制器不存在的情况做定制,而不是所有404,那可以替换默认的控制器选择器:
先创建自定义选择器类:
public class CustomControllerSelector : DefaultHttpControllerSelector { private readonly HttpConfiguration _config; public CustomControllerSelector(HttpConfiguration config) : base(config) { _config = config; } public override HttpControllerDescriptor SelectController(HttpRequestMessage request) { try { // 尝试用默认逻辑找控制器 return base.SelectController(request); } catch (HttpResponseException ex) { // 如果是找不到控制器的404 if (ex.Response.StatusCode == HttpStatusCode.NotFound) { // 自定义响应内容 var customResponse = request.CreateResponse(HttpStatusCode.NotFound, new { Error = "指定的API控制器不存在", RequestedPath = request.RequestUri.AbsolutePath }); // 抛出带自定义响应的异常 throw new HttpResponseException(customResponse); } // 其他异常就原样抛出 throw; } } }
同样在WebApiConfig里替换默认的选择器:
public static void Register(HttpConfiguration config) { // 替换默认控制器选择器 config.Services.Replace(typeof(IHttpControllerSelector), new CustomControllerSelector(config)); // 原有路由配置 config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); }
两种方案选哪个看你的需求:方案一适合统一所有404的格式,方案二更精准,只处理控制器不存在的场景。
内容的提问来源于stack exchange,提问作者Robert N. Dean
相关产品推荐
相关产品推荐

