You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:21:27