2

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.

Community
  • 1
  • 1
Shaggy
  • 5,422
  • 28
  • 98
  • 163
  • Your try/catch is does not do anything, you are catching and then reshowing the same exception, this is the same as not catching it at all. If you want to swallow the exception then don't throw in your catch block. – Ben Robinson Oct 27 '14 at 09:49
  • @BenRobinson : even if i remove throw from catch block. when line in finally gets executed, exception gets catched outer most catch block – Shaggy Oct 27 '14 at 10:08

3 Answers3

5

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);
    }
}
Community
  • 1
  • 1
Kami
  • 19,134
  • 4
  • 51
  • 63
  • I tried both your solution suggested `Server.Execute` doesnt redirect my page & when the finally block gets executed it further throws exception – Shaggy Oct 27 '14 at 10:13
  • @Shaggy I have added an example. Remember, `Server.Execute` works like a function call, it will return control back to the executing application. So, you need to manually end the response or break out of a procedure. – Kami Oct 27 '14 at 10:24
  • 1
    now on `Response.End()` it throwing same error after using `Server.Execute` – Shaggy Oct 27 '14 at 10:28
  • @Shaggy . . . I do not have your code here, so I cannot envision every single error that might occur. As suggested, use `return` instead. – Kami Oct 27 '14 at 10:29
  • @Shaggy I think I might not be explaining this clearly. If you need a redirect, use `Server.Transfer` with empty `catch`, if you need the code to run from the other page, use `Server.Execute`. – Kami Oct 27 '14 at 10:36
0

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.

Koen
  • 634
  • 3
  • 14
0

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>");
Manish Goswami
  • 863
  • 10
  • 27