C# – How to redirect browser during an Async Postback

asp.netasp.net-3.5asp.net-ajaxcpostback

The scenario

I have an ASP.NET project which uses a custom authorization/authentication method (vs. using forms/windows authentication, etc.). On each secure page load, the following code is executed:

protected void Page_Load(Object sender, EventArgs e)
{
    if (!IsLoggedIn)
    {
        HttpContext.Current.Response.Redirect("~/Login/", true);
    }
}

This code basically checks whether the user is still logged in (no expired ASP.NET session, not logged out, etc.); if the user is not logged in, a Response.Redirect() happens, sending them to the login page.

This scenario works perfectly fine when the user requests a full page (through a link, or direct URL). The issue arises when using an async postback!

I have a button nested inside of an <asp:UpdatePanel>, which cause async postbacks when clicked. This button updates an <asp:Label />. For example:

<!-- the button -->
<asp:LinkButton ID="MyButton" CausesValidation="false" Text="My Button" OnClick="MyButton_Click" runat="server" />

<!-- the label -->
<asp:Label ID="MyLabel" runat="server" />
protected void MyButton_Click(Object sender, EventArgs e)
{
    MyLabel.Text = DateTime.Now.ToString();
}

The issue

When an async postback is executing, and IsLoggedIn is false, the request is redirected to the login page. Now, the ASP.NET Framework expects a specific response (rather than an HTML page); thus, throwing the following error:

enter image description here

The question

How can I solve this issue? How can I force the whole page redirect to a specific address from the code-behind during an async postback?

Best Answer

While Kenneth's answer is the appropriate method of redirecting, I needed something a little more custom.

During an async postback, I needed to simulate Response.Redirect("path", true) - the true parameter (Indicates whether execution of the current page should terminate) is the important thing I needed to replicate! Simply using Response.End() after ScriptManager.RegisterClientScriptBlock() would not work because then there would be no response sent back to the browser.

By analyzing the server response to an async postback, I resorted to using the following hack (simulating a response by using Response.Write):

String jsRedirect = String.Format("window.location.pathname = '{0}';", VirtualPathUtility.ToAbsolute(url));

Response.Write(
    // required parameters!
    "0|asyncPostBackControlIDs|||" +
    "0|postBackControlIDs|||" +
    "0|updatePanelIDs|||" +
    "0|childUpdatePanelIDs|||" +
    "0|panelsToRefreshIDs|||" +

    // your custom JavaScript
    String.Format("{0}|scriptBlock|ScriptContentNoTags|{1}|", jsRedirect.Length, jsRedirect)
);
Response.Flush();
Response.End();