Response.Redirect(URL, false) - post-redirect event management

jweekes picture jweekes · Jan 23, 2013 · Viewed 10.2k times · Source

Possible Duplicate:
Response.Redirect causes System.Threading.ThreadAbortException

ASP/C#.NET (web forms, not MVC)

UPDATE: Just found a related post (likely rendering this a duplicate): Why Response.Redirect causes System.Threading.ThreadAbortException?

~ ~ ~

After a good bit of research, I have come to the understanding that, in general, when using Response.Redirect(), it is better to pass FALSE for the second parameter, to avoid System.Threading.ThreadAbortException. (http://blogs.msdn.com/b/tmarq/archive/2009/06/25/correct-use-of-system-web-httpresponse-redirect.aspx)

My question is, "Is there a recommended way (pattern) for managing (namely skipping) processing in page events that fire after the redirect, when false is passed for the second parameter?"

This is mostly a problem for me when I am checking for and redirecting on an expired session in Page_Load(). It seems very tedious to have to perhaps set a "_Redirected" flag every time I redirect and then check that flag at the top of every event. I haven't had to worry about this in the past because I always passed TRUE for the second parameter, not knowing any better.

Below is some code showing what I don't want to have to do (check _Redirected before processing each event). Perhaps what I'm looking for is a better Session Expiration Processing pattern.

Any suggestions on how to improve this processing, would be greatly appreciated.

private bool _Redirected = false;    

protected void Page_Load(object sender, EventArgs e)
{
  if (Session["key"] == null)
  {
    Response.Redirect("SessionExpired.aspx", false);
    Context.ApplicationInstance.CompleteRequest();

    _Redirected = true;
  }       
}

protected void Page_PreRender(object sender, EventArgs e)
{
  if (!_Redirected)
  {
    // do Page_PreRender() stuff...
  }
}

protected void Button1_Click(object sender, EventArgs e)
{
  if (!_Redirected)
  {
    // do Button1_Click() stuff...

    Response.Redirect("Button1Page.aspx", false);
    Context.ApplicationInstance.CompleteRequest();

    _Redirected = true;
  }
}

protected void Button2_Click(object sender, EventArgs e)
{
  if (!_Redirected)
  {
    // do Button2_Click() stuff...

    Response.Redirect("Button2Page.aspx", false);
    Context.ApplicationInstance.CompleteRequest();

    _Redirected = true;
  }
}

~ ~ ~

[01/24/2013] In response to https://stackoverflow.com/users/2424/chris-lively (thank you, btw), here is simplified code that I believe is similar to what you tested. I am still seeing Button1_Click() execute on post back after the Response.Redirect(url, false) with .CompleteRequest() in Page_Load().

protected void Page_Load(object sender, EventArgs e)
{
  if (this.IsPostBack)
  {
    Response.Redirect("Redirect.aspx", false);
    Context.ApplicationInstance.CompleteRequest();
  }
}

protected void Button1_Click(object sender, EventArgs e)
{
  Response.Write("Button1 clicked!");
}

This behavior is corroborated by this response https://stackoverflow.com/a/12957854/1530187 to the similar post I noted above in my update.

Any idea what I'm doing wrong that would cause the page to continue executing after redirect?

Answer

NotMe picture NotMe · Jan 23, 2013

You referenced a pretty good article, but your code doesn't reflect what the author suggested as a way to do this "correctly". Namely:

protected void Page_Load(object sender, EventArgs e)
{
  if (Session["key"] == null)
  {
    Response.Redirect("SessionExpired.aspx", false);
    Context.ApplicationInstance.CompleteRequest();
  }       
}

UPDATE
I put together a very simple sample application. All it had was two form pages.
The first page had a button on it that did a response.write. I put a breakpoint on this line. In the page_load method I put a redirect followed immediately by a call to CompleteRequest. This redirect occured was set to occur if the page was posting back.

All the second page did was emit "hello"

I then ran the application, which pulled up the first form. I clicked the button. The break point was never hit and it redirected. This was exactly what I expected it to do. Namely, the page_load method caught the postback, performed a redirect and completed the request immediately without further processing of the page.

This means that there is absolutely no reason to put the if (!_Redirected) code in each of your button clicks. All you need to do is copy/ paste the code I have at the top of this answer. It will prevent those clicks from being called.