Compartilhar via


Detecting Server.Transfer

How do you know when a page is being rendered as the result of a Server.Transfer, rather than a Response.Redirect or the user browsing directly to a page?

Actually it’s quite easy, assuming you’re using the default ASP.NET pipeline. In reality the “thing” that is responsible for handling an HTTP request is aptly called an HttpHandler – that is, they implement the IHttpHandler interface. Of course, you can create your own handlers if you just want to return a document, or your own manually rendered content, or similar.

But... the Page class also implements IHttpHandler, and ASP.NET therefore uses some cleverness to work out which page should be rendered, and then uses an instance of that Page-derived class as the HttpHandler.

So the bottom line is that if you do a Server.Transfer, the HttpHandler for the request will be the page that was originally being rendered... Therefore, the following code when executed from within a page will display “true” if a Server.Transfer has occurred;

TransferredLabel.Text = (Context.Handler != this).ToString();

Easy huh? Try the attached if you want to see this in action.

DetectingServerTransfer.zip

Comments

  • Anonymous
    July 13, 2009
    And how do you know if it is redirected?

  • Anonymous
    July 13, 2009
    There is no magic way I'm afraid as a redirect is processed as a completely seperate HTTP request from the button click (or whatever initiated the Response.Redirect). I should also say that I think this isn't such a bad thing - trying to customise the ASP.NET pipeline or behaviour too much often leads to headaches and maintainability problems. I've seen people use all sorts of tokens in the URL or cookies to indicate it was Redirected... but if you need to know this in the page there's a good chance you've taken an approach that doesn't fit well with ASP.NET. The only reasons why detecting a Server.Transfer can be so useful is to try and avoid doing expensive tasks twice (if they were done in the transferring page already for example), or to pick up on data posted to the previous page's controls. Hope that makes sense! Simon

  • Anonymous
    October 05, 2009
    Thank you - this is just what I was looking for.

  • Anonymous
    November 30, 2010
    I know this is an old thread, but this is the top Google result for "detect server transfer." I devised a much cleaner way of doing this using the HTTP response headers. I was using this for recaptcha validation, so I implemented the following on my page base class: private const string cCaptchaHeaderKey = "X-Captcha"; private const string cCaptchaAcceptedValue = "Accepted"; public bool CaptchaAccepted {  get  {    return (Response.Headers.Get(cCaptchaHeaderKey) == cCaptchaAcceptedValue);  }  set  {    if (value)      Response.Headers.Set(cCaptchaHeaderKey, cCaptchaAcceptedValue);    else if (Response.Headers.Get(cCaptchaHeaderKey) != null)      Response.Headers.Remove(cCaptchaHeaderKey);  } }

  • Anonymous
    December 01, 2010
    @ Captain (and lol at your screen name!) I've re-read that 5 times and I'm still not sure I see what you're doing. You're storing a flag in the response headers collection to indicate you've already done something? I'm not convinced that is "cleaner" than; public bool Transferred {   get   {      return (Context.Handler != this);   } } Surely that's simpler??!! Simon