3

在大多数情况下,我的 404 错误自定义错误页面被正确调用。但是,一些 url 跳过我的自定义错误页面并调用 iis 404 错误页面。为什么会这样?

这是一个在 IIS 7.5 上运行的 MVC 4 项目

//This invokes my Custom 404 error page.
http://192.168.1.10/test1/test2/test3

//This bypasses my Custom 404 and invokes the iis 404 error page.
http://192.168.1.10/test1/test2/test3/test4

//Web.config
<system.web>
  <customErrors mode="On" defaultRedirect="Error">
    <error statusCode="404" redirect="Error404" />
  </customErrors>
...

//Route
routes.MapRoute(
    name: "Error404",
    url: "error404",
    defaults: new { controller = "Error", action = "Error404" }
);

//Error Controller
public ActionResult Error404()
{
    Response.StatusCode = 404;
    Response.TrySkipIisCustomErrors = true;

    return View();
}
4

3 回答 3

3

我也不确定为什么您的自定义错误有时似乎会绕过,但让我向您展示我在 MVC4 网站上所做的事情。

第一,我RouteCollection在 RouteConfig.cs 中创建了一个包罗万象的路由:

routes.MapRoute(
   name: "CatchAll",
   url: "{*catchall}",
   defaults: new { controller = "Error", action = "Index", statusCode = 404, error = new HttpException(404, "Route not found via RouteConfig.") });

第二,我创建了一个Controller名为Error. 唯一的工作是处理网站中抛出的异常:

public class ErrorController : Controller
    {
        public ActionResult Index(int statusCode, Exception error)
        {
            ErrorViewModel vm = new ErrorViewModel();
            vm.CurrentException = error;
            vm.InnerException = error.InnerException ?? null;
            vm.StatusCode = statusCode;

            Response.StatusCode = statusCode;
            Response.TrySkipIisCustomErrors = true;

            return View(vm);
        }
    }

我正在使用 ErrorViewModel 来显示 HTML 源代码中的详细错误。

第三,在 中Global.asax,我重写了Application_Error捕获网站中每个异常的方法,并通过Error在步骤 1 中创建的控制器处理它们:

protected void Application_Error(object sender, EventArgs e)
        {
            Exception exception = Server.GetLastError();
            Server.ClearError();

            RouteData routeData = new RouteData();
            routeData.Values.Add("controller", "Error");
            routeData.Values.Add("action", "Index");
            routeData.Values.Add("error", exception);

            if (exception.GetType() == typeof(HttpException))
            {
                routeData.Values.Add("statusCode", ((HttpException)exception).GetHttpCode());
            }
            else
            {
                routeData.Values.Add("statusCode", 500);
            }

            IController controller = new ErrorController();
            controller.Execute(new RequestContext(new HttpContextWrapper(Context), routeData));
        }

就是这样,我从 web.config 中删除了 CustomErrors 节点。这个答案的很大一部分是在这篇博文中找到的

Response.TrySkipIisCustomErrors = true;

是覆盖 IIS 404 页面的关键。

希望能帮助到你!

于 2013-03-03T02:50:18.827 回答
2

所以我自己做了这个练习,这就是我所做的。

  1. 安装了 Magical Unicorn Mvc Error Toolkit @ http://nuget.org/packages/MagicalUnicorn.MvcErrorToolkit/(我用过 nuget)
  2. 按照自述文件中的设置说明@ https://github.com/PureKrome/WorldDomination.Web.Mvc.ErrorHandling
  3. 您的(我们的)应用程序由于一个非常具体的原因而失败:传入的请求与任何路由(包括“默认”路由)不匹配,并且由于错误而落入 IIS。您需要做的是在“默认”路由下方的 RouteConfig.cs(对于 MVC4)的最底部添加以下路由:

        routes.MapRoute(
            name: "Catchall",
            url: "{*url}",
            defaults: new { controller = "Error", action = "404" }
        );
    

这样做的目的是防止执行返回错误并返回 IIS,并让您的应用程序有最后一次机会弹出 404。

一个示例 url:http: //yoursite.com/some/fake/route将按预期命中您的默认路由和 404(假设您没有带有接受参数 Route 的 Fake 操作的 Some 控制器)。

一旦您添加了一个 url 段,例如http://yoursite.com/some/fake/route/die,您需要全部捕获来处理它。

路由定义中的 * 允许您捕获输入的尽可能多的 url 段,而不必为每种可能的情况添加一个(这也是不可能的)。请记住,这是一般情况下的解决方案......您可能有其他路由(超过 3 个 url 段)并且可能需要稍微调整它(例如,这些路由声明需要在 RouteConfig.cs 中更高比包罗万象)。

于 2013-05-17T18:38:47.733 回答
0

这是项目源,可能对您有所帮助https://github.com/13daysaweek/Mvc4CustomErrorPage

于 2015-05-25T08:07:09.813 回答