【问题标题】:Best way to implement a 404 in ASP.NET在 ASP.NET 中实现 404 的最佳方法
【发布时间】:2010-10-14 14:26:18
【问题描述】:

我正在尝试确定在标准 ASP.NET Web 应用程序中实现 404 页面的最佳方式。我目前在 Global.asax 文件中的 Application_Error 事件中捕获 404 错误并重定向到友好的 404.aspx 页面。问题是请求看到 302 重定向,然后是 404 页面丢失。有没有办法绕过重定向并立即响应包含友好错误消息的 404?

Googlebot 等网络爬虫是否关心对不存在页面的请求是否返回 302 后跟 404?

【问题讨论】:

    标签: asp.net http-status-code-404


    【解决方案1】:

    在 Global.asax 的 OnError 事件中处理这个问题:

    protected void Application_Error(object sender, EventArgs e){
      // An error has occured on a .Net page.
      var serverError = Server.GetLastError() as HttpException;
    
      if (serverError != null){
        if (serverError.GetHttpCode() == 404){
          Server.ClearError();
          Server.Transfer("/Errors/404.aspx");
        }
      }
    }
    

    在你的错误页面中,你应该确保你正确设置了状态码:

    // If you're running under IIS 7 in Integrated mode set use this line to override
    // IIS errors:
    Response.TrySkipIisCustomErrors = true;
    
    // Set status code and message; you could also use the HttpStatusCode enum:
    // System.Net.HttpStatusCode.NotFound
    Response.StatusCode = 404;
    Response.StatusDescription = "Page not found";
    

    您还可以很好地处理这里的各种其他错误代码。

    Google 通常会遵循 302,然后遵守 404 状态代码 - 因此您需要确保在错误页面上返回该代码。

    【讨论】:

    • 完美。我忘记了 Server.Transfer() 方法。我已经在使用 Application_Error 事件,所以现在我只调用 Server.Transfer() 而不是 Response.Redirect()。
    • 至少在 IIS 7 中,上述内容甚至没有 302 临时重定向。对我来说,问题是发现 Server.ClearError() 对于 404 是必不可少的(否则仍然进行重定向,而不是转移)。
    • 404.htm页面是否应该是.aspx页面,以便您可以在代码隐藏中添加Response.StatusCode = 404?
    • @codeulike:很好,这是一个 MCMS 实例的副本,它使用 ISAPI 过滤器将 url 映射到其数据库中的内容,因此忽略了扩展名。有问题的页面后面确实有一个 .aspx 页面。
    • TrySkipIisCustomErrors 正是我所需要的。不错。
    【解决方案2】:

    您可以使用 web.config 将 404 错误发送到自定义页面。

        <customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm">
            <error statusCode="403" redirect="NoAccess.htm" />
            <error statusCode="404" redirect="FileNotFound.htm" />
        </customErrors>
    

    【讨论】:

    • 我试过这个,它似乎仍然以 302 响应 FileNotFound.htm。也许 FileNotFound.htm 返回了 404,但初始响应仍然是 302 重定向。你看到同样的东西吗?
    • 这本身会导致 302(至少对于 IIS 7)。应该: 1. 对 404 执行上述自定义错误。 2. 在 Application_Error(global.asax 或错误模块)中检查 404,如果是:Server.ClearError(); Server.Transfer("/page-not-found.aspx"); 3.在404页面:Response.Status = "404 Not Found"; Response.StatusCode = 404;
    • 如果将 redirectMode="ResponseRewrite" 添加到 它将重定向。在发送“404 Not Found”状态代码之前,它也不会发送“302 Found”状态代码。您可以随时查看 msdn 的链接:msdn.microsoft.com/en-us/library/h0hfz6fc.aspx
    【解决方案3】:

    最简单的答案:不要在代码中这样做,而是 configure IIS instead

    【讨论】:

      【解决方案4】:

      我也遇到了 302 而不是 404。我设法通过执行以下操作来修复它:

      控制器:

      public ViewResult Display404NotFoundPage()
              {
                  Response.StatusCode = 404;  // this line fixed it.
      
                  return View();
              }
      

      查看:

      向用户显示一些错误消息。

      web.config:

      <customErrors mode="On"  redirectMode="ResponseRedirect">
            <error statusCode="404" redirect="~/404NotFound/" />
      </customErrors>
      

      最后是 RouthConfig:

      routes.MapRoute(
                   name: "ErrorPage",
                   url: "404NotFound/",
                   defaults: new { controller = "Pages", action = "Display404NotFoundPage" }
               );
      

      【讨论】:

        【解决方案5】:

        我非常喜欢这种方法:它创建一个视图来处理所有错误类型并覆盖 IIS。

        [1]:从 Web.config 中删除所有“customErrors”和“httpErrors”

        [2]:检查 'App_Start/FilterConfig.cs' 看起来像这样:

        public class FilterConfig
        {
            public static void RegisterGlobalFilters(GlobalFilterCollection filters)
            {
                filters.Add(new HandleErrorAttribute());
            }
        }
        

        [3]:在'Global.asax'中添加这个方法:

        public void Application_Error(Object sender, EventArgs e)
        {
            Exception exception = Server.GetLastError();
            Server.ClearError();
        
            var routeData = new RouteData();
            routeData.Values.Add("controller", "ErrorPage");
            routeData.Values.Add("action", "Error");
            routeData.Values.Add("exception", exception);
        
            if (exception.GetType() == typeof(HttpException))
            {
                routeData.Values.Add("statusCode", ((HttpException)exception).GetHttpCode());
            }
            else
            {
                routeData.Values.Add("statusCode", 500);
            }
        
            Response.TrySkipIisCustomErrors = true;
            IController controller = new ErrorPageController();
            controller.Execute(new RequestContext(new HttpContextWrapper(Context), routeData));
            Response.End();
        }
        

        [4]: 添加'Controllers/ErrorPageController.cs'

        public class ErrorPageController : Controller
        {
            public ActionResult Error(int statusCode, Exception exception)
            {
                Response.StatusCode = statusCode;
                ViewBag.StatusCode = statusCode + " Error";
                return View();
            }
        }
        

        [5]:在“视图/共享/Error.cshtml”中

        @model System.Web.Mvc.HandleErrorInfo
        @{
            ViewBag.Title = (!String.IsNullOrEmpty(ViewBag.StatusCode)) ? ViewBag.StatusCode : "500 Error";
        }
        
         <h1 class="error">@(!String.IsNullOrEmpty(ViewBag.StatusCode) ? ViewBag.StatusCode : "500 Error"):</h1>
        
        
        //@Model.ActionName
        //@Model.ContollerName
        //@Model.Exception.Message
        //@Model.Exception.StackTrace
        

        :D

        【讨论】:

        • 这很整洁:)
        【解决方案6】:

        你在任何地方都用这个吗?

         Response.Status="404 Page Not Found"
        

        【讨论】:

          【解决方案7】:

          我可以看到在 web.config 中设置 404 页面是一种很好的干净方法,但它最初仍会以 302 重定向响应到错误页面。例如,如果您导航到:

          https://stackoverflow.com/x.aspx

          您将通过 302 重定向重定向到:

          https://stackoverflow.com/404?aspxerrorpath=/x.aspx

          我想要发生的事情是这样的:

          http://www.cnn.com/x.aspx

          没有重定向。对丢失 URL 的请求会返回 404 状态代码和友好的错误消息。

          【讨论】:

            【解决方案8】:

            您可以将 IIS 本身配置为返回特定页面以响应任何类型的 http 错误(包括 404)。

            【讨论】:

              【解决方案9】:

              我认为最好的方法是在您的 web.config 中使用自定义错误结构,如下所示,这让您可以连接页面以简单有效的方式处理所有不同的 HTTP 代码。

                <customErrors mode="On" defaultRedirect="~/500.aspx">
                   <error statusCode="404" redirect="~/404.aspx" />
                   <error statusCode="500" redirect="~/500.aspx" />
                </customErrors>
              

              【讨论】:

                猜你喜欢
                • 2011-01-12
                • 2010-09-07
                • 2011-11-10
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2013-05-08
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多