Shaggy
Shaggy

Reputation: 5790

ThreadAbortException in server transfer in asp.net

I am getting error Unable to evaluate expression because the code is optimized or a native frame is on top of the call stack. while executing line

Server.Transfer("Payment.aspx?vpc_ChannelId=2", true);

so as pointed out by this answer https://stackoverflow.com/a/1252119/1169180 & https://stackoverflow.com/a/11130517/1169180

i changed my code to

  protected void Page_Load(object sender, EventArgs e)
{
    try
    {
    UserContext conObj = new UserContext();
    HttpContext CurrContext = HttpContext.Current;
    if (!IsPostBack)
    {
        // Code
    }
    else
    {
        string userContext = hdnContextObj.Value;
        conObj = JsonConvert.DeserializeObject<UserContext>(userContext);
        CurrContext.Items.Add("Context", conObj);
        try
        {
        Server.Transfer("Payment.aspx?vpc_ChannelId=2", true);
        }
        catch (ThreadAbortException xObj)
        {
        }
        finally
        {
        Server.Transfer("Payment.aspx?vpc_ChannelId=2", true);
        }
    }
    }
    catch (Exception xObj)
    {
    Response.Write("Exception : " + xObj.Message);
    }
}

still i am getting same exception in out catch block

Also as pointed out here http://support.microsoft.com/kb/312629/EN-US/ i used Server.Execute but it didnt redirect to Payment.aspx page instead it just refreshes.

Upvotes: 2

Views: 4442

Answers (3)

Kami
Kami

Reputation: 19407

The exception is raised because the thread running the operation is forced to terminate in multiple locations due to the transfer. As such, it is safe to ignore this exception as your linked answers suggest.

You can ignore the exception by catching the exception and not throwing it.

try
{
    Server.Transfer("Payment.aspx?vpc_ChannelId=2", true);
}
catch(ThreadAbortException)
{
    // Exception ignored: Thread Abort = discontinue processing on the current page
}

Alternatively, as the MSDN article suggest, you can use Server.Execute instead.

To work around this problem, use one of the following methods:

  • For Response.End, call the HttpContext.Current.ApplicationInstance.CompleteRequest method instead of Response.End to bypass the code execution to the Application_EndRequest event.

  • For Response.Redirect, use an overload, 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);
    

    If you use this workaround, the code that follows Response.Redirect is executed.

  • For Server.Transfer, use the Server.Execute method instead.

// Clarification on Server.Execute

The MSDN doc clarifies the usage of Server.Execute. It is important to remember this is not a redirect, it acts like a function call. So any code after the call will also be executed. If you do not want the code to execute you can use a return, or Response.End.

In the OP's example, his code might look something like this when using Server.Execute

protected void Page_Load(object sender, EventArgs e)
{
    try
    {
       UserContext conObj = new UserContext();
       HttpContext CurrContext = HttpContext.Current;
       if (!IsPostBack)
       {
           // Code
       }
       else
       {
           string userContext = hdnContextObj.Value;
           conObj = JsonConvert.DeserializeObject<UserContext>(userContext);
           CurrContext.Items.Add("Context", conObj);
           Server.Execute("Payment.aspx?vpc_ChannelId=2", true);
           Response.End(); // or return;
       }
    }
    catch (Exception xObj)
    {
       Response.Write("Exception : " + xObj.Message);
    }
}

Upvotes: 6

Manish Goswami
Manish Goswami

Reputation: 865

ThreadAbortException exception caused because Response.End called both in Server.Redirect and Server.Transfer internally.Try something like this

    Response.Write("<script language=\"javascript\" type=\"text/javascript\">window.location.href = 'Your.aspx'; </script>");

Upvotes: 0

Koen
Koen

Reputation: 644

Server.Transfer("Payment.aspx?vpc_ChannelId=2", false);

This will work for you. It stops the rest of the remaining code after the transfer code, so that it will not execute that code.

Upvotes: 0

Related Questions