【问题标题】:How to redirect browser during an Async Postback?如何在异步回发期间重定向浏览器?
【发布时间】:2013-04-02 20:24:49
【问题描述】:

场景

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

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

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

当用户请求完整页面(通过链接或直接 URL)时,此方案工作得很好。使用异步回发时会出现问题!

我有一个嵌套在 <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 为假时,请求被重定向到登录页面。现在,ASP.NET 框架需要一个特定的响应(而不是 HTML 页面);因此,抛出以下错误:

问题

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

【问题讨论】:

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


    【解决方案1】:

    虽然Kenneth's answer 是合适的重定向方法,但我需要更多自定义

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

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

    【讨论】:

    • 非常详细的答案。确实,在您要中止当前请求的处理的约束下,这应该是公认的答案。
    【解决方案2】:

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

    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";,它只会进行客户端重定向。

    【讨论】:

    • 虽然您的回答是实现预期结果的最适当方式,但我需要一点更多;我需要在当前状态下中断页面生命周期(就像Response.Redirect("path", true) 所做的那样)。我已经发布了一个额外的答案,提供了这个额外的细节。
    【解决方案3】:

    这里存在一些术语误解。 “异步回发”在技术上根本不是回发;这是一个xmlHttpRequest。如果要在此处进行重定向,则必须在 javascript 中使用 window.open() 在 ajax 回调函数中完成。

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

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

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

    【讨论】:

    • 感谢您对术语的澄清 - 不幸的是,我只是使用在 ASP.NET WebForms 世界中广泛使用的术语。我将如何捕捉这些重定向?如您所见,它们不是有意重定向,而是授权/身份验证的副作用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-24
    • 1970-01-01
    • 1970-01-01
    • 2011-08-01
    相关资源
    最近更新 更多