May 24, 2009

Response.Redirect in try catch finally block

We all have likely used the Redirect() method of the Response object. Basically, the Response objects redirects the user to view a different URL and a page from the server end. Few days back, I used the Redirect() method from within a try-catch-finally block and noticed unexpected behavior.

I first created a try-catch block with a Response.Redirect("page2.aspx") and then ran the method like below.

protected void Page_Load(object sender, EventArgs e)
{
string status = string.Empty;
try
{
status = "try";
Response.Redirect("page2.aspx?status"+status);
}
catch (Exception ex)
{
status="catch";
Response.Redirect("page2.aspx?status=" + status);
}
finally
{
status="finally";
Response.Redirect("page2.aspx?status="+status);
}

}

The page redirected to page2.aspx?status=finally. The try section got processed first and set the value of status variable to "try" and "throw" an exception System.Threading.ThreadAbortException. This exception is caused since the page is trying to kill the current thread.

The catch section is then processed and set the status variable to "catch". Then Response.Redirect("page2.aspx?status=" + status); in the catch section is then processed which instead of redirecting the page, transfers the control to the finally block. In the finally block, the status variable is set the "finally" and the page is then redirected to page2.aspx?status=finally. Commenting out the finally block shows an exception occurred in the try block.

To avoid having a System.Threading.ThreadAbortException caused by a Response.Redirect() in the try block, set the endResponse parameter to false.

Response.Redirect("page2.aspx?status=" + status, false);

In the next example, I changed the try block to throw an exception instead of doing a Response.Redirect() like below.
protected void Page_Load(object sender, EventArgs e)
{
string status = string.Empty;
try
{
status = "try";
throw new Exception();
//Response.Redirect("page2.aspx?status="+status, false);
}
catch (Exception ex)
{
status="catch";
Response.Redirect("page2.aspx?status=" + status, true);
}
finally
{
status="finally";
//Response.Redirect("page2.aspx?status="+status);
}

}

When I started debugging the page, a new page opened in the browser with url page2.aspx?status=catch. I thought the status property will get overridden in the finally block but the page redirected to page with query string status=catch. What happened here is an exception was thrown in the try block which transferred the control to catch section. When the catch section was processed, status was changed to "catch" and the redirected url for Response.Redirect was constructed. The url was then page2.aspx?status=catch. Instead of redirecting the page then, the control was transferred to finally block. The status variable was changed to "finally". The control was then transferred to the catch block's Response.Redirect. The url was already set to have query string status=catch. So, in the browser the url page2.aspx?status=catch was shown.

If I uncomment the Response.Redirect in the finally block, the url page2.aspx?status=finally will be shown in the browser.

0 comments:

Reference: Shahed Kazi at AspNetify.com