【问题标题】:Page refresh Vs IsPostBack页面刷新与 IsPostBack
【发布时间】:2011-01-25 20:21:04
【问题描述】:

我有一个索引页面,它将用户发送到不同浏览器选项卡上的编辑产品页面。

对于每个编辑的产品,索引都会重写 Session["ProductID"]。

然后编辑页面具有以下代码,以便为该选项卡和产品提供唯一标识符:

if (!IsPostBack) //first time page load
{
    Random R = new Random(DateTime.Now.Millisecond + DateTime.Now.Second * 1000 + DateTime.Now.Minute * 60000 + DateTime.Now.Minute * 3600000);
    PageID.Value = R.Next().ToString();

    Session[PageID.Value + "ProductID"] = Session["ProductID"];
}

这可行,当同一个用户打开多个选项卡时,我只在我的代码中引用 Session[PageID.Value + "ProductID"] 以便我始终拥有正确的 ID。 (我在受信任的环境中工作,这是针对 Intranet 的,因此我对安全级别不太在意)。

如果用户通过按 F5 键刷新页面,就会出现我的问题。此时 Session[PageID.Value + "ProductID"] 获取他打开的最后一个产品的 Session["ProductID"]。

例如:

用户1在tab1中打开product1

用户1在tab2中打开product2

每当他们正常使用该工具时,一切正常。但是如果:

product1页面上的用户1点击刷新按钮(F5)product1页面变成product2页面

有没有办法从“第一次加载/从另一个页面重定向”检测页面刷新,以便我可以告诉我的页面不要更新我的 Session[PageID.Value + "ProductID"]?

【问题讨论】:

  • 值得快速测试一下Request.Headers["HttpReferer"]的存在是否有效。
  • 我尝试了 Request.UrlReferrer.ToString() ,当我第一次加载页面时,我将索引页面作为引荐来源。不幸的是,如果我用 F5 刷新页面,我仍然会得到索引页面。推荐人更改的唯一方法是,如果我在编辑页面上进行回发,那么推荐人将成为编辑页面。

标签: c# .net asp.net


【解决方案1】:

就个人而言,我会选择 URL 参数。例如。将产品 ID 作为 URL 参数传递。

如果你需要没有参数的页面,你可以例如

  1. 将参数传递给页面。
  2. 如果参数存在,页面会自行重新加载并删除参数

这样你可以区分第一次调用(=参数存在)和第二次+调用(参数不存在)。

【讨论】:

  • 我明白了,但是如果我重新加载页面,我的特定于该页面的 Session[PageID.Value + "ProductID"] 将会消失。如果我然后检查查询字符串以取回 ID 并且字符串不存在,我该怎么办?如果我留下字符串,任何人都可以去更改查询字符串的 ID 并访问他们不应该访问的内容。还是我理解错了?
  • 关于你的“访问他们不应该访问的东西”:我通常使用数据库中的权限表来实现这样的场景(例如“对产品 1 有权限”并检查登录用户的权限)请求的产品页面的页面。
【解决方案2】:

我通过存储两个版本的状态识别参数解决了一个非常相似的问题:一个在 Session 中,一个在 ViewState 或 URL (QueryString) 中。

如果您比较 Page_Load 上的两个值,这将告诉您会话变量自页面首次加载以来是否已更改。这应该正是您所需要的。

编辑:粗略的代码草图(警告 - 自从我 3 年前编写以来,还没有看到实际代码):

protected string currentProductID
{
    get
    {
        return Request.QueryString["ProductID"];
        //or: 
        //return (string)ViewState["ProductID"];
        //or:
        //return HiddenField1.Value;
    }
    set
    {
        Response.Redirect(ResolveUrl("~/MyPage.aspx?ProductID=" + value));
        //or:
        //ViewState.Add("ProductID", value);
        //or: 
        //HiddenField1.Value = value;
    }
}

protected void Page_Load(object sender, EventArgs e)
{
    //If the problem only occurs when not posting back, wrap the below in
    // an if(!IsPostBack) block. My past issue occurred on both postbacks
    // and page refreshes.

    //Note: I'm assuming Session["ProductID"] should never be null.

    if (currentProductID == null)
    {
        //Loading page for the first time.
        currentProductID = (string)Session["ProductID"];
    }
    else if (currentProductID != Session["ProductID"])
    {
        //ProductID has changed since the page was first loaded, so react accordingly. 
        //You can use the original ProductID from the first load, or reset it to match the one in the Session.
        //If you use the earlier one, you may or may not want to reset the one in Session to match.
    }
}

在上面的代码中,注意对 ViewState 的改变(包括一个 Hidden 控件的值)只会在下一个 PostBack 时生效。刷新时,它们将恢复为最新值。就我而言,这就是我想要的,但听起来它不太适合您的情况。不过,这些信息可能对您有用,具体取决于您如何实施。

我没有讨论比较currentProductIDSession[PageID.Value + "ProductID"],因为我已经发布了很多代码,我不知道你想要做什么的细节。但是您可以通过多种方式使用 Session、ViewState 和 QueryString 来收集有关页面状态和历史记录的信息。

希望这能给你一个大致的想法。如果这还不足以让您继续前进,请告诉我。

【讨论】:

  • 我有点看到你要去哪里,但不知道如何实现。你有一些代码或我可以参考的东西吗?谢谢!
  • 感谢您的代码。不幸的是,它似乎没有更新。 currentProductID 第一次加载页面时为空,然后获取 ProductID 会话的值。但是当我按 F5 或点击重新加载页面时,该值会重置回 null 并始终返回到第一个 if。
  • @LanFeusT:您使用的是 ViewState 还是 URL 查询字符串? URL 中的任何内容都应该在刷新时可用。您是否有机会在某处的代码中重置它?
  • 我正在尝试使用 ViewState,因为我不想在 URL 中看到产品 ID。
  • @LanFeusT 抱歉,我花了一段时间才注意到您的最后评论。如果是我,我会重新考虑将它放在 URL 中——无论是在查询字符串中还是在路径中的某个位置,可能使用 URL 重写。这似乎是最好的方法,它是正确使用 GET 参数恕我直言。亚马逊就是这样做的,这对我有一定的影响。否则,我可能会选择 mjw06d 的链接。
【解决方案3】:

您可能想看看this。我认为它与您要查找的内容很接近。

【讨论】:

  • 这可能会起作用,尽管我想找到一个 c# 解决方案。更糟糕的情况我会恢复到这个谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-09
  • 2016-12-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-04
相关资源
最近更新 更多