Wednesday, April 23, 2008

Unable to evaluate expression because the code is optimized or a native frame is on top of the call stack

Recently, I got a weird error in my ASP.NET page:
Unable to evaluate expression because the code is optimized or a native frame is on top of the call stack
This is what I was trying to do:

protected override void Page_Load(object sender, EventArgs e)
{
try
{
..
..
if (! IsUserAuthorized(i))
{
RedirectToParentPage();
return;
}
..
..
}
catch (Exception ex)
{
//Do something
..
}
}


private void RedirectToParentPage()

{

Response.Redirect(nextpage.aspx);

}
As usual, I googled and found a few related articles. There is one that I found on Microsoft support site http://support.microsoft.com/kb/312629/EN-US/. It states that both Response.Redirect and Server.Transfer methods call Response.End internally. The Response.End method ends the page execution and shifts the execution to the Application_EndRequest event in the application's event pipeline. The line of code that follows Response.End is not executed. This results in a ThreadAbortException exception. This clearly explains why the above piece of code resulted in this exception.
The article suggests that we use an overload of Response.Redirect Response.Redirect(String url, bool endResponse) that passes false for the endResponse parameter to suppress the internal call to Response.End.
For example:
Response.Redirect(nextpage.aspx, false);
Also, I noticed that this problem occurred only if the Response.Redirect was enclosed in a try-catch block since I had a similar piece of code somewhere else, but which was not exclosed in a try-catch block. I couldn’t remove the try-catch block since it was required for some existing code written there.
One more option would be enclose the Response.Redirect in a specific try-catch block that caught ThreadAbortException exception and do nothing in catch block. This is certainly not the right way to code.

Hence, I modified the above code as shown below:

protected override void Page_Load(object sender, EventArgs e)

{
try
{
..
..
if (! IsUserAuthorized(i))
{
RedirectToParentPage();
return;
}
..
..
}
catch (Exception ex)
{
//Do something
..
}
}

private void RedirectToParentPage()
{

/* Use an overload of Response.Redirect to suppress the call to Response.End method. The Response.End method ends the page execution and shifts the execution to the Application_EndRequest event in the application's event piipeline. The line of code that follows Response.End is not executed. This results in a ThreadAbortException exception. */

Response.Redirect(nextpage.aspx);

/* Call CompleteRequest method to to bypass the code execution to the Application_EndRequest event. */
HttpContext.Current.ApplicationInstance.CompleteRequest();
}
}





1 comment:

DotNetGuts said...

For Solution:
http://dotnetguts.blogspot.com/2009/01/unable-to-evaluate-expression-because.html