Server.TransferRequest()和http状态代码

时间:2011-02-14 20:25:40

标签: c# asp.net sharepoint httpmodule

我必须实现一个自定义的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?

更新

我在sharepoint环境之外尝试了这个,并且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;
    }
}

2 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:2)

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

您可能希望编写HTTP处理程序(或处理Global.asax中的事件),以便在提供404 Not Found时强制状态标头为PageNotFoundUrl