ASP.NET: Using Server.TransferRequest
By Peter Bromberg
If you haven't heard about this new method, don't be surprised - it is not well documented. You will only be able to use the method if you're hosting your pages on IIS 7 or higher --it doesn't work with previous versions of IIS.
For the page programmer, it is similar to the old Transfer method, but
better. When you issue a Server.Transfer, you're basically creating a new
instance of the default page destination and executing it. It's fast, but
there are some problems with it. If you are writing a module, there
is no way to get a reference to that new page since it would be instantiated
"in-place" in the current request.
The new TransferRequest
method performs a complete request by using an IIS 7 worker thread.
This means that the page request will go through the complete ASP.NET pipeline,
giving every module a chance of interacting with the request. This means that
authorization will be applied to the new url you're asking for. Another
advantage is that you can redirect to any handler. You can even define the headers
that will be passed to the new handler you're asking for since one of the
overloads of the method expects NameValueCollection parameter.
So
HttpServerUtility.TransferRequest performs a full IIS child request under the
covers, which allows it to re-run the entire request pipeline for the new request
as if it was a separate request, getting the correct configuration for it, and
running all of the normal IIS modules including authentication, authorization,
etc. For example, IIS will apply the authorization rules for the new
url, as opposed to the previous url.
It does have one issue: if
the parent request (the one from which you call TransferRequest) has acquired
session state, then you need to release it before calling the method. If
you don't, then the new request will block for several seconds. This will
affect mostly pages since the problem won't appear if you call the method
before the AcquireRequestState or after the ReleaseRequestState HttpApplication
events.
This happens because if the parent request has acquired
session state and calls TransferRequest, it will wait until the child
request finishes in order to execute the end request notifications. The end request
notifications is the place where the request releases the session state (if it
has acquired it). When the child request starts executing, it tries to get
the session state which hasn't been released by the parent request. so, we're
in a dead lock scenario with a built-in timeout.
There's a workaround
for this if you need it. The idea is to make sure that the parent request will
release the session before starting the child request. To achieve this, you can
call the CompleteRequest method and then, from within a method that handles the
EndRequest event raised by the HttpApplication, you should perform the TransferRequest
method call. Here's a global.asax file that shows how to achieve this:
<%@
classname="MySample" %>
<script language="C#" runat="server">
string _transferRequestPath;
public void TransferRequest(string path) {
// remember the path for later
_transferRequestPath = path;
// short circuit the pipeline by jumping to the
// end request notifications where we can release
// session state
this.CompleteRequest();
}
// In Session_Start, we acquire session state. This will
// cause TransferRequest to hang unless we release session state first.
void Session_Start() {
}
// By the time Application_EndRequest is called, session state has been released
void Application_EndRequest() {
// we may need to call TransferRequest
if (_transferRequestPath != null) {
// make copy of path and set instance field to null
// since application instances are pooled and reused.
string path = _transferRequestPath;
_transferRequestPath
= null;
Context.Server.TransferRequest(path);
}
}
</script>
Mike Volodarsky has more information on this:.
Popularity (1896 Views)
 |
| Biography - Peter Bromberg |
Peter Bromberg is a C# MVP, MCP, and .NET expert who has worked in banking, financial and telephony for over 20 years. Pete focuses exclusively on the .NET Platform, and currently develops SOA and other .NET applications for a Fortune 500 clientele. Peter enjoys producing digital photo collage with Maya,playing jazz flute, the beach, and fine wines. You can view Peter's UnBlog and IttyUrl sites.
|  |
|
|
Article Discussion: ASP.NET: Using Server.TransferRequest