“正常回发”和“页面创建为PreviousPage”之间的区别

时间:2011-04-29 09:44:22

标签: c# asp.net webforms postback

ASP.net webforms页面有两种情况我想区分:“正常回发”以及创建页面时因为下一页调用了PreviousPage

  • 第1页出现正常后退
    • IsPostbacktrue
    • IsCrossPagePostBackfalse

  • 第2页有Server.Transfer("page2.aspx"),第2页使用PreviousPage,因此虚拟地创建了第1页。对于第1页:
    • IsPostbacktrue
    • IsCrossPagePostBackfalse

您可以看到IsPostBackIsCrossPagePostBack没有帮助,因为它们在两种情况下都是相同的。

我之所以这样问:

我有第1页,它通过跨页回发(第1页中设置的PostBackUrl="page2.aspx")将数据发送到第2页。对于启用了javascript的所有用户,此工作正常。

但我也希望对已禁用javascript的用户进行回退。对于他们来说,单击第1页上的提交按钮不会导致第2页,而是返回到页面1.页面1现在可以检测到这一点并执行Server.Transfer("page2.aspx")到第2页。问题是:何时页面2使用PreviousPage然后再次创建第1页,并且会一次又一次地执行Server.Transfer() ...

我的解决方法是Server.Transfer不在Page_Load事件中但仅在Page_PreRender事件中执行,因为此事件仅在正常回发时发生,而不是在该页面创建为PreviousPage 这种解决方法有效,但非常脏。如果我可以区分Page_Load事件中已经存在的两种情况,那就更好了。

这可能吗?

1 个答案:

答案 0 :(得分:1)

当您从第1页到第2页执行HttpServerUtility.Transfer时,HttpContext然后在第1页和第2页之间共享。因此,通常,一个请求意味着一个请求处理程序(通常是一个页面)和一个请求上下文。但在这种情况下,有两个处理程序和一个(共享)上下文。您可以使用上下文在两个处理程序之间共享有关请求的信息。

因此,一个解决方案可能是将第2页所需的所有数据放入HttpContext.Items中。然后首先检查这些数据。如果存在,则知道控制是通过Server.Transfer传输的,并且它不应该通过PreviousPage调用第1页。相反,它现在应该从上下文中获取数据。

<强> Page1.aspx的

protected void Page_Load(object sender, EventArgs e)
{
    if(IsPostBack && HttpContext.Items.Contains("CrossPagePostBack") == false)
    {
       // Cross page postback did not succeed (JavaScript disabled)
       string name = NameTextBox.Text;
       HttpContext.Items.Add("Name", name);

       HttpContext.Items.Add("Transfer", true);
       Server.Transfer("Page2.aspx");
    }
}

<强> Page2.aspx

protected void Page_Load()
{
    if(IsPostBack)
    {
        string name;
        if(CrossPagePostBack)
        {
            // Cross page postback succeeded (JavaScript was enabled)
            HttpContext.Items.Add("CrossPagePostBack", true);
            name = PreviousPage.NameTextBox.Text;
        }
        else if (HttpContext.Items.Contains("Transfer"))
        {
            // We got transferred to from Page1.aspx
            name = (string)HttpContext.Items["Name"];
        }

        // Do something with Page 1's form value(s)
    }
}

或者你可以转过头来让HttpContext.Items添加一个标记(“Page 2就在这里”),然后第1页检查那个标记。如果它存在则不需要再次传输(打破循环)。 如果对PreviousPage的调用也导致共享请求上下文,我不能100%确定。

<强> Page1.aspx的

protected void Page_Load(object sender, EventArgs e)
{
    if(IsPostBack && HttpContext.Items.Contains("CrossPagePostBack") == false)
    {
        // Cross page postback did not succeed (JavaScript disabled)
       if(HttpContext.Items.Contains("Transfer"))
       {
           // We did not yet transfer to Page 2
           HttpContext.Items.Add("Transfer", true);
           Server.Transfer("Page2.aspx");
       }
    }
}

<强> Page2.aspx

protected void Page_Load()
{
    if(IsPostBack) 
    {        
        if(CrossPagePostback)
        {
            // Cross page postback succeeded (JavaScript enabled)
            HttpContext.Items.Add("CrossPagePostBack", true);
        }

        string name = PreviousPage.NameTextBox.Text;

        // Do something with Page 1's form value(s)
    }
}

第二种方法在实现上更简单,特别是如果第1页上的表单很复杂。你只有一个地方可以阅读第1页的形式,你只需要在HttpContext.Items中添加一个简单的布尔值。