12

我正在使用使用 ASP.NET<customErrors>指令的通用错误页面。

<customErrors mode="On" defaultRedirect="500.html" redirectMode="ResponseRewrite">
</customErrors>

问题 - 发生错误时,此页面不返回 HTTP 状态“500”。它是 200。所以链接检查器和蜘蛛程序看不到有任何问题。

如何将 500 HTTP 状态与静态 500.html 页面一起发送?

要求:

  • 我必须使用 redirectMode="ResponseRewrite"
  • 我不能使用动态页面,只能使用静态 .html。
4

6 回答 6

8

customErrors 元素的 MSDN 文档声明它由 System.Web.Configuration.CustomErrorsSection 实现。如果我们使用 Red Gate 的 .NET Reflector 来分析该类,我们可以看到该设置在框架中的使用位置。

它由 System.Web.UI.Page.HandleError 和 System.Web.HttpResponse.ReportRuntimeError 使用。

这两个最终都调用 System.Web.HttpResponse.RedirectToErrorPage。(此方法的名称令人困惑:重要的是要注意 RedirectToErrorPage 将 redirectMode 设置作为参数,因此即使您使用的是 ResponseRewrite 并且实际上没有发生重定向,它也会被调用。)

RedirectToErrorPage 方法的相关部分是:

    if (redirectMode == CustomErrorsRedirectMode.ResponseRewrite)
    {
        this.Context.Server.Execute(url);
    }

似乎没有任何方法可以在错误处理中设置响应代码:归根结底,它只是一个普通的 Server.Execute。因此,您似乎不可避免地需要编写代码来实现所需的 HTTP 响应。

你能重新检查一下为什么要使用普通的 .html 文件吗?这似乎是错误处理的明智选择,因为您不希望在可能导致发生另一个错误时经历 .aspx 页面的所有开销。

但也许有一些中间立场会像 .html 文件一样健壮?

例如,您可以制作一个预编译的 HttpHandler,将其注册到 URL /500.error,然后将 500.error 设为您的默认重定向页面。(这类似于 ScriptResource.axd 的工作方式。)如果您将模块预编译为 DLL(而不是从普通的旧 .axd 文件进行动态编译),您可能会发现它在面对错误情况。如果您遇到一个错误,即使这也不起作用,那么静态 .html 文件可能也不起作用 - 请记住,customErrors 指令仍然依赖于在后台运行的 .NET,并且仍然使用 StaticFileHandler 来提供服务你的 .html 文件。

或者,您可以考虑在 IIS 应用程序前面使用反向代理,即使面对应用程序池的灾难性故障,它也可以提供友好的 500 页。这将需要更多的工作来设置,但会比 customErrors 更健壮,例如,如果您的 web.config 损坏,即使 customErrors 也不起作用。

于 2010-08-27T08:56:18.220 回答
4

在您的 gllobal.asax 文件中添加以下代码

protected void Application_EndRequest(object sender, EventArgs e)
    {
        if (Request.Url.AbsolutePath.EndsWith("500.html"))
            Response.StatusCode = 500;
    }
于 2010-08-21T06:54:01.907 回答
3

好的,我有一个解决方案,我可以让它工作的唯一方法是绕过 Web 配置文件中的自定义错误部分。

所以,一个例子 default.aspx

public partial class Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        throw new Exception("boom");
    }
}

然后在 global.asax 文件中:

protected void Application_Error(object sender, EventArgs e)
{
    // Clear the error to take control of process
    Server.ClearError();

    Response.WriteFile(Server.MapPath("500.html"));
    Response.StatusCode = 500;
    Response.StatusDescription = "Internal Server Error";
}

您可能可以为 500.html 部分编写更好的处理机制 - 我认为这应该可以实现您想要实现的目标。

仅使用 VS Cassini Web 服务器进行了测试,但是我看不出为什么这在 iis6 中不起作用。

于 2010-08-24T20:11:09.883 回答
1

尝试像这样配置您的自定义错误部分:

<customErrors mode="On" redirectMode="ResponseRewrite">
  <error statusCode="500" redirect="500.aspx">
</customErrors>

在您的 500.aspx 文件中,更改 page_load 中的响应代码;

Response.StatusCode = 500;
Response.StatusDescription = "Internal Server Error";
于 2010-08-19T20:17:28.903 回答
0

这可以通过 isapi 过滤器来完成。它必须用 c 编写,但它可以修改 .html 请求的响应状态,以便浏览器在您的自定义 html 页面中获得 500。

于 2010-08-27T17:01:43.367 回答
-1

如果您坚持更改核心 HTTP 信号,那么您要么必须满足某些要求,要么准备编写自己的 Web 服务器。是的,您必须运行 IIS7 集成的 AppPool 并且您仍然可能必须接受重定向到活动页面,因为您试图假装您的服务器已关闭并且服务器并非旨在假装自杀。因此,如果它为您提供了一种简单的方法,您可以选择表示感谢或开发自己的非 HTTP 兼容服务器,该服务器将随意扰乱响应代码。

于 2010-08-26T13:46:41.150 回答