Is there a way to fake the behavior of TransferRequest in IIS 6? Specifically the ability to re-process the whole pipeline without the client having to make a new request?
I'm trying to handle a 404 error from Application_Error, do some magic to see if the URL changed (in which case I use Response.Redirect to redirect to the new URL) but if there really is a 404 I want to serve up my pretty looking 404 page which has to deal with showing some content which is part of the users session.
The problem is that if I use Server.Transfer, The request context is null at this point so my 404 page crashes. I don't want to use Request.Redirect because I want the browser URL to still be on the missing URL so the 404 status code gets interpreted properly for the missing resource.
On IIS 7 I can use TransferRequest which does exactly what I want. The browser retains the missing URL and Session context is available for the 404 page code. So is there a way to do something similar with IIS 6? (TransferRequest is only available in IIS 7 in Pipeline mode and our production servers are still on IIS 6)
One possible solution is to make your redirect with a flag, and then make RewritePath on BeginRequest.
For example, you place this code on Global.asax
protected void Application_BeginRequest(Object sender, EventArgs e)
{
if (HttpContext.Current.Request.RawUrl.EndsWith("error"))
{
HttpContext.Current.RewritePath("404CoolPage.aspx", false);
}
// .... rest code
}
and you make the redirect on your
void Application_Error(object sender, EventArgs e)
{
//... code
if(System.Web.HttpContext.Current.Request.QueryString.Count > 0)
Response.Redirect(HttpContext.Current.Request.RawUrl + "&error");
else
Response.Redirect(HttpContext.Current.Request.RawUrl + "?error");
}
This way, you make the redirect, and you keep the url as it is.
My Error Setup
By the way, I use the the Server.Transfer and Its working to me. This is my Error setup and the Transfer is done using the server, I am not sure where your page have problem with the request context
void Application_Error(object sender, EventArgs e)
{
// ... log the errors ...
string cTheFile = HttpContext.Current.Request.Path;
// in case the error is inside the 404CoolError.aspx
// I check for not calling my self and get a dead loop.
if(!cTheFile.EndsWith("404CoolError.aspx"))
Server.Transfer("~/404CoolError.aspx");
}
and on web.config
<customErrors redirectMode="ResponseRewrite" ... />
From what I gather there is no standard way to simulate TransferRequest
on IIS 6 - at least not without a major rewrite of most of your code.
the only other options available (besides Transfer
which you pointed out that it does not do what you need) are:
I would suspect that with some fiddling you could create a solution which is as close as you can get with IIS6 using Execute
although I am not sure that performance will be good.
Regarding RewritePath
you could start with with something like this and extend it to to do what you want:
HttpContext.Current.RewritePath(url, false);
IHttpHandler httpHandler = new YourHTTPHandler(); // use your HttpHandler !
httpHandler.ProcessRequest(HttpContext.Current);
You could set up a custom error handler in IIS. In the web site properties page, on the custom errors tab, edit '404' and set it to '404.aspx' (or whatever). Move your 'magic' code to the 404 page. If you find a real 404, then there is no need to 'transfer' anywhere - just let your page display.