代码之家  ›  专栏  ›  技术社区  ›  Ben Mills

在ASP.NET中实现404的最佳方法

  •  34
  • Ben Mills  · 技术社区  · 17 年前

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

    如果对一个不存在的页面的请求返回302后跟404,那么像GoogleBot这样的网络爬虫会关心这个问题吗?

    9 回复  |  直到 8 年前
        1
  •  41
  •   Toolkit    8 年前

    在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";
    

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

    谷歌通常会遵循302,然后遵守404状态代码-所以你需要确保你在错误页面上返回它。

        2
  •  14
  •   Robin Day    17 年前

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

        <customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm">
            <error statusCode="403" redirect="NoAccess.htm" />
            <error statusCode="404" redirect="FileNotFound.htm" />
        </customErrors>
    
        3
  •  3
  •   Pontus Gagge    17 年前

    最简单的答案:不要用代码来做,但是 configure IIS instead .

        4
  •  3
  •   Eyal Patrick    12 年前

    我也面对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
  •  2
  •   Ian G    17 年前

    你在哪里用这个?

     Response.Status="404 Page Not Found"
    
        6
  •  2
  •   Community Mohan Dere    9 年前

    我可以看到,在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状态代码,其中包含一条友好的错误消息。

        7
  •  2
  •   ubik404    11 年前

    我真的很喜欢这种方法:它创建一个视图来处理所有错误类型并重写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]:在“views/shared/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

        8
  •  0
  •   Assaf Lavie    17 年前

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

        9
  •  0
  •   James    13 年前

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

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