如何在异步回发期间重定向浏览器?

时间:2013-04-02 20:24:49

标签: c# asp.net asp.net-ajax postback asp.net-3.5

方案

我有一个ASP.NET项目,它使用自定义授权/身份验证方法(与使用表单/ Windows身份验证等)。在每个安全页面加载时,执行以下代码:

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

此代码基本上检查用户是否仍然登录(没有过期的ASP.NET会话,没有注销等);如果用户未登录,则会发生Response.Redirect(),将其发送到登录页面。

当用户请求整页(通过链接或直接网址)时,此方案可以正常运行。使用异步回发时出现问题!

我有一个嵌套在<asp:UpdatePanel>内的按钮,当单击时会导致异步回发。此按钮更新<asp:Label />。例如:

<!-- 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();
}

问题

当执行异步回发并且IsLoggedIn为false时,请求重定向到登录页面。现在,ASP.NET Framework需要一个特定的响应(而不是HTML页面);因此,抛出以下错误:

enter image description here

问题

我该如何解决这个问题?如何在异步回发期间强制整个页面从代码隐藏重定向到特定地址?

3 个答案:

答案 0 :(得分:4)

虽然Kenneth's answer是适当的重定向方法,但我还需要一些自定义

在异步回发期间,我需要模拟Response.Redirect("path", true) - true 参数(表示当前页面的执行是否应该终止)是我需要复制的重要的东西!只需在Response.End()之后使用ScriptManager.RegisterClientScriptBlock()就行不通,因为这样就不会有任何回复发送回浏览器。

通过分析服务器对异步回发的响应,我使用了以下hack(使用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();

答案 1 :(得分:3)

如果你想从代码隐藏中触发,你可以这样做:

if (ScriptManager.GetCurrent(Page).IsInAsyncPostBack) {
    ScriptManager.RegisterStartupScript(updatepanelid, typeof(string), "redirect", "window.location = 'http://www.google.com';", true);
} else {
    Response.Redirect("http://www.google.com");
}

另请注意,如果您使用window.open(),则会打开一个弹出窗口(可能会阻止也可能不会阻止)。如果您使用window.location = "someurl";,它只会执行客户端重定向。

答案 2 :(得分:0)

这里有一些术语误解。 “Async postback”在技术上根本不是回发;它是xmlHttpRequest。如果你想在这里进行重定向,必须使用window.open()在ajax回调函数中使用javascript完成。

我不确定如何使用asp.net AJAX实现这一点。在服务器上执行xmlHttpRequest代码期间,不可能重定向客户端(澄清 - 您可能重定向,但您回复的html将是(如你的情况)由asp.NET的javascript ajax代码错误地解析。

使用jQuery,这将是一个伪解决方案。

$.ajax({
    success: function(data) {
        if (data == 'redirect') {
            window.open('yourRedirectUrl');
        }
    }
});