ASP.Net Web API 2.0中CustomErrors mode="On"无法跳转至自定义错误页
我来帮你一步步排查和解决这个问题,ASP.NET Web API的错误处理逻辑和普通MVC项目有不少区别,你遇到的情况主要是这几个点没处理到位:
1. 必须创建Error控制器(核心缺失)
你只在Shared文件夹加了Error.cshtml视图,但没有对应的Error控制器,ASP.NET没法找到~/Error路径的处理程序,直接就 fallback到IIS默认错误页了。
如果你的项目是MVC+Web API混合项目(要返回HTML视图的话更适合这个),创建如下控制器:
public class ErrorController : Controller { public ActionResult Index() { // 可以在这里获取错误状态码,比如从Request里取 var statusCode = (int)TempData["StatusCode"] ?? 500; ViewBag.StatusCode = statusCode; return View(); } }
要是纯Web API项目,你可能需要返回JSON错误,但既然要跳转页面,混合MVC的方式更合适。
2. Web API的异常不会触发Application_Error
默认情况下,Web API有自己独立的异常处理管道,Global.asax里的Application_Error只处理MVC/Web Forms的错误,对Web API的未处理异常无效。
要捕获Web API的异常,你可以自定义全局异常过滤器:
public class WebApiExceptionFilter : ExceptionFilterAttribute { public override void OnException(HttpActionExecutedContext context) { // 先记录异常日志(可选) // Logger.Error(context.Exception, "Web API未处理异常"); // 重定向到错误页 var response = context.Request.CreateResponse(HttpStatusCode.Redirect); response.Headers.Location = new Uri("/Error", UriKind.Relative); context.Response = response; } }
然后在WebApiConfig.cs里注册这个过滤器:
public static class WebApiConfig { public static void Register(HttpConfiguration config) { // 其他路由配置... config.Filters.Add(new WebApiExceptionFilter()); } }
3. IIS级别的404需要额外配置
当请求完全匹配不到任何ASP.NET路由(比如输入了完全不存在的路径),这个请求会直接由IIS处理,不会进入ASP.NET管道,这时候<customErrors>就失效了。
你需要在web.config的<system.webServer>节点下添加<httpErrors>配置,覆盖IIS的默认错误页:
<system.webServer> <httpErrors errorMode="Custom" existingResponse="Replace"> <!-- 移除默认的404错误配置 --> <remove statusCode="404" subStatusCode="-1" /> <!-- 自定义404跳转 --> <error statusCode="404" path="/Error" responseMode="Redirect" /> <!-- 处理500错误 --> <remove statusCode="500" subStatusCode="-1" /> <error statusCode="500" path="/Error" responseMode="Redirect" /> </httpErrors> </system.webServer>
注意:responseMode="Redirect"会改变URL,如果你想保持原URL返回错误页,可以用responseMode="ExecuteURL",但需要确保/Error路径能正确处理。
4. 确保路由能匹配到Error控制器
检查你的RouteConfig.cs(MVC路由)里有没有添加Error路由:
public class RouteConfig { public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); // 添加Error路由 routes.MapRoute( name: "Error", url: "Error", defaults: new { controller = "Error", action = "Index" } ); // 其他默认路由... routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } ); } }
最后验证步骤
- 启动项目,访问一个不存在的路径,应该会跳转到你的
Error.cshtml页面 - 手动触发一个Web API的未处理异常(比如在某个Action里
throw new Exception()),检查是否会跳转到错误页 - 调试时查看
WebApiExceptionFilter的OnException方法是否被触发
内容的提问来源于stack exchange,提问作者rajk

