I had to implement a custom HttpModule to handle a 404 error in Sharepoint.
It listens for the PreSendRequestContent event, and looks for a 404 status code. If one is found it does a 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);
}
}
This works just fine, but I noticed in Fiddler that the page is showing a 200 status code, even though the original request was a 404. This is not good for search engines.
Is this an expected behaviour of TransferRequest? Can I somehow maintain the 404 status code? Or, would I have been better off using a good old fashioned Server.Transfer?
Update
I tried this outside of a sharepoint environment, and the Server.TransferRequest request does indeed give a 200 status code, removing the 404. Server.Transfer doesn't work as I don't think it can given the pipeline.
Update 2
Thanks to the answer below, I have added the following:
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;
}
}