错误500而不是404
错误500而不是404
我有一个asp.net MVC 5项目,我想抛出404错误而不是500错误。
错误信息如下:
控制器'ProjetX.Controllers.HomeController'上找不到公共操作方法'something'
和
路径'/something'上找不到控制器或者控制器没有实现IController接口
我理解为什么是500错误,但我希望抛出404错误,这对于SEO更好。
我无法弄清楚如何做到这一点。
以下是我的代码:
我的Elmah的ExceptionHandler类
public class HandleCustomError : HandleErrorAttribute { public override void OnException(ExceptionContext filterContext) { //如果异常已经处理,我们什么也不做 if (filterContext.ExceptionHandled) { return; } else { //使用Elmah记录异常 Log(filterContext); Type exceptionType = filterContext.Exception.GetType(); //如果是ajax调用时的异常 if (exceptionType == typeof(ExceptionForAjax)) { filterContext.HttpContext.Response.Clear(); filterContext.HttpContext.Response.ContentEncoding = Encoding.UTF8; filterContext.HttpContext.Response.HeaderEncoding = Encoding.UTF8; filterContext.HttpContext.Response.TrySkipIisCustomErrors = true; filterContext.HttpContext.Response.StatusCode = 500; filterContext.HttpContext.Response.StatusDescription = filterContext.Exception.Message; } else { base.OnException(filterContext); } } //确保将异常标记为已处理 filterContext.ExceptionHandled = true; } private void Log(ExceptionContext context) { //获取此请求的当前HttpContext实例 HttpContext httpContext = context.HttpContext.ApplicationInstance.Context; if (httpContext == null) { return; } //将异常包装在HttpUnhandledException中,以便ELMAH可以捕获原始错误页面 Exception exceptionToRaise = new HttpUnhandledException(message: null, innerException: context.Exception); //将异常发送给ELMAH(用于记录、发送邮件、过滤等) ErrorSignal signal = ErrorSignal.FromContext(httpContext); signal.Raise(exceptionToRaise, httpContext); } }
我如何添加自定义错误
public static void RegisterGlobalFilters(GlobalFilterCollection filters) { filters.Add(new HandleCustomError()); }
路由配置
public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute("Robots.txt", "robots.txt", new { controller = "robot", action = "index" }); routes.MapRoute( name: "Localization", url: "{lang}/{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }, constraints: new { lang = @"^[a-zA-Z]{2}$" } ); routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } ); routes.MapRoute( "NotFound", "{*url}", new { controller = "Error", action = "Error404" } ); routes.MapMvcAttributeRoutes(); }
我的webconfig
我希望在HandleCustomError类中处理错误,但问题是它直接进入我的错误控制器中的Error500操作。
奇怪的是错误仍然在elmah中记录。
它没有触发HandleCustomError类中的任何断点,错误是如何记录的?
谢谢
问题出现的原因是在路由配置中,没有正确处理404错误的情况。解决方法是添加一个名为"NotFound"的路由,将所有无法匹配的URL重定向到Error控制器的Error404动作。
具体代码如下:
public class RouteConfig { public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( name: "Localization", url: "{lang}/{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }, constraints: new { lang = @"^[a-zA-Z]{2}$", controller = GetAllControllersAsRegex(), action = GetAllActionsAsRegex } ); routes.MapRoute( "Default", "{controller}/{action}/{id}", new { controller = "Home", action = "Index", id = UrlParameter.Optional }, new { controller = GetAllControllersAsRegex(), action = GetAllActionsAsRegex() } ); routes.MapRoute( "NotFound", "{*url}", new { controller = "Error", action = "Error404" } ); routes.MapMvcAttributeRoutes(); } private static string GetAllControllersAsRegex() { var controllers = typeof(MvcApplication).Assembly.GetTypes() .Where(t => t.IsSubclassOf(typeof(Controller))); var controllerNames = controllers .Select(c => c.Name.Replace("Controller", "")); return string.Format("({0})", string.Join("|", controllerNames)); } private static string GetAllActionsAsRegex() { Assembly asm = Assembly.GetExecutingAssembly(); var actions = asm.GetTypes() .Where(type => typeof(Controller).IsAssignableFrom(type)) //filter controllers .SelectMany(type => type.GetMethods()) .Where(method => method.IsPublic && !method.IsDefined(typeof(NonActionAttribute))) .Select(x=>x.Name); return string.Format("({0})", string.Join("|", actions)); } }
以上是该问题的解决方案,可以从这个地址查看更多详情:https://stackoverflow.com/a/4668252