【问题标题】:Server.TransferRequest() and the http status codeServer.TransferRequest() 和 http 状态码
【发布时间】:2011-02-14 20:25:39
【问题描述】:

我必须实现一个自定义 HttpModule 来处理 Sharepoint 中的 404 错误。

它侦听 PreSendRequestContent 事件,并查找 404 状态代码。如果找到一个,它会执行 TransferRequest。

void App_PreSendRequestContent(object sender, EventArgs e)
{
    HttpResponse res = App.Response;
    HttpRequest req = App.Request;

    if (res.StatusCode == 404 && !req.Url.AbsolutePath.Equals(PageNotFoundUrl, StringComparison.InvariantCultureIgnoreCase))
    {
        App.Server.TransferRequest(PageNotFoundUrl);
    }
}

这很好用,但我注意到在 Fiddler 中页面显示了 200 状态代码,即使原始请求是 404。这对搜索引擎不利。

这是TransferRequest 的预期行为吗?我可以以某种方式维护 404 状态码吗?或者,使用老式的 Server.Transfer 会更好吗?

更新

我在共享点环境之外尝试过这个,Server.TransferRequest 请求确实给出了 200 状态代码,删除了 404。Server.Transfer 不起作用,因为我认为它不能提供管道。

更新 2

感谢下面的回答,我添加了以下内容:

void App_PostRequestHandlerExecute(object sender, EventArgs e)
{
    HttpResponse res = App.Response;
    HttpRequest req = App.Request;

    if (req.Url.AbsolutePath.Equals(PageNotFoundUrl, StringComparison.InvariantCultureIgnoreCase))
    {
        res.StatusCode = 404;
    }
}

【问题讨论】:

  • 你的 web.config 是什么样子的?对我来说,更改 Response.StatusCode 将使 IIS7 丢弃整个响应并返回处理错误,使我所有的自定义错误处理代码都是徒劳的。
  • @asbjornu - 除了添加 httpModule 之外,我没有对 web.config 进行任何更改
  • 这很奇怪。每当我设置Response.StatusCode 时,IIS7 都会接管整个响应并呈现它自己的自定义错误处理内容。
  • 您在使用共享点吗? Sharepoint 有大量模块可以跳入管道,因此它与普通的 .net 应用程序不同。
  • 我没有使用 SharePoint,没有。

标签: c# asp.net sharepoint httpmodule


【解决方案1】:

好吧,TransferRequest() 触发了一个新请求,这意味着一个新的响应。由于PageNotFoundUrl 指向的资源确实存在,因此客户端会收到一个合法的200 OK 状态标头。

您可能想要编写一个 HTTP 处理程序(或处理 Global.asax 中的事件),以便在为 PageNotFoundUrl 提供服务时将状态标头强制为 404 Not Found。

【讨论】:

  • 这也是有道理的,特别是因为我已经有了一个 httpmodule。我应该在哪里检查这个?
  • @ScottE, PostRequestHandlerExecute 应该合适。
  • 完美,我喜欢,谢谢。已更新问题以包含此解决方案。
  • 在 IIS7 中,我无法更改状态码。如果我这样做了,IIS 将接管响应并呈现它自己的 HTTP 正文,而不管我在自定义错误处理中可能呈现了什么。
  • @asbjornu: Response.TrySkipIisCustomErrors = true;
【解决方案2】:

Server.TransferRequest 不会更改状态代码。它在不告诉客户端的情况下将请求的控制权传递到另一个页面。您可以在 Page_Load 事件中手动设置自定义 404 页面中的状态码:

protected void Page_Load(object sender, System.EventArgs e)
{
    Response.StatusCode         = 404;
    Response.StatusDescription  = "Not Found";
}

【讨论】:

  • 这是有道理的。不幸的是,在 sharepoint 中,这意味着部署一个发出此状态代码的 Web 部件……但除此之外它工作得很好。
  • 另外,我认为您在第一段中的说法不正确-您自己尝试一下。在页面上设置 404 状态码,然后执行 Server.TransferRequest() - 您会看到 404 变成了请求转移到的页面返回的任何状态码。顺便说一句,当我说“看到”时,我并不是说两个标题都会出现,只是测试开/关会证明这一点。
  • 如果您在Server.TransferRequest的目标页面中设置状态码,它就可以工作。这就是我为我的网站所做的。
猜你喜欢
  • 2015-07-21
  • 2012-06-16
  • 2011-04-06
  • 2015-12-29
  • 2010-12-15
  • 2013-04-04
  • 2014-09-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多