• 屏蔽刷新提交后台


    现象:当页面进行过数据提交(PostBack)后,如果通过点击【F5】或者浏览器的【刷新】按钮,

        此时页面会模拟浏览器的上次的提交事件,如果做的是数据插入操作,将有可能导致数据的多次插入。

    原因:浏览器会模拟上次提交的数据在次提交,并在此触发上次提交的时间。

    对策:

    针对此,网上已经有各种各样的处理方法。大概有以下的两类:

    1。通过在事件中,在插入数据之前做主键冲突判定。

    2。在HttpHandler中添加票据处理,然后在事件处理中判断是否是刷新进行提交的。 

    两种方法都需要对事件做特殊的处理,对于项目维护的复杂度有所增加,尤其是第一种需要做数据的逻辑判断,已经影响到了业务逻辑,这是很不好的方法。

      然而,我们是否可以让浏览器的刷新成为我们真正想要的刷新,即从新访问页面,而不是模拟上次的提交数据。

    其实如果大家对第二种方式熟悉的话,他就是我们想要的方式,然而他需要每个页面的事件都做判断,因而维护程度较复杂,针对此本人做了一些改进。

    具体修改方案如下:

     1.在页面中声明两个HiddenField,第一个存储前台页面的票据,第二存储后台Session票据的Key。

    2.如果前台的票据和Session的票据不相同,则即为刷新,此时DeterminePostBackMode方法返回空,以使页面置为 非PostBack的状态。

    3.在OnPreRenderComplete中同步HiddenField和Session中的票据。

    为了让各个页面对此事不可见的,将上述逻辑完全封装到Basepage中,使页面完全不需做其他处理。

    实例:

    BasePage:

    BasePage
     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 
     6 namespace DonkeyControl
     7 {
     8     public class BasePage : System.Web.UI.Page
     9     {
    10         private static string PAGE_REFRESH_TICKET_KEY = "__PageRefreshTicketKey";
    11         private string PAGE_SESSION_REFRESH_TICKET_KEY = "__PageSessionRefreshTicketKey";
    12 
    13         /// <summary>
    14         /// 判断是否是PostBack
    15         /// </summary>
    16         /// <returns></returns>
    17         protected override System.Collections.Specialized.NameValueCollection DeterminePostBackMode()
    18         {
    19             //如果是通过"刷新"提交的后台,将页面强行设置成非PostBack模式,以实现刷新以重新的访问页面的形式进行
    20             if (IsRefreshed)
    21             {
    22                 return null;
    23             }
    24             return base.DeterminePostBackMode();
    25         }
    26 
    27         protected override void OnPreRenderComplete(EventArgs e)
    28         {
    29             SynchroRefreshTicket();
    30             base.OnPreRenderComplete(e);
    31         }
    32 
    33         /// <summary>
    34         /// 同步页面和后台Session的票据
    35         /// </summary>
    36         private void SynchroRefreshTicket()
    37         {
    38             if (!Page.IsPostBack)
    39             {
    40                 string strTicket = Guid.NewGuid().ToString();
    41                 ClientScript.RegisterHiddenField(PAGE_REFRESH_TICKET_KEY, strTicket);
    42                 ClientScript.RegisterHiddenField(PAGE_SESSION_REFRESH_TICKET_KEY, strTicket);
    43                 Session[strTicket] = strTicket;
    44             }
    45             else
    46             {
    47                 string strTicket = Guid.NewGuid().ToString();
    48                 ClientScript.RegisterHiddenField(PAGE_REFRESH_TICKET_KEY, strTicket);
    49                 ClientScript.RegisterHiddenField(PAGE_SESSION_REFRESH_TICKET_KEY, Request.Form[PAGE_SESSION_REFRESH_TICKET_KEY]);
    50                 Session[Request.Form[PAGE_SESSION_REFRESH_TICKET_KEY]] = strTicket;
    51             }
    52         }
    53 
    54 
    55         /// <summary>
    56         /// 比较HiddenField的票据和Session中存储的票据是否相同,如果不相同则为通过刷新的方式进行的提交
    57         /// </summary>
    58         protected bool IsRefreshed
    59         {
    60             get
    61             {
    62                 if(string.Equals(Request.Form.Get(PAGE_REFRESH_TICKET_KEY),Session[Request.Form.Get(PAGE_SESSION_REFRESH_TICKET_KEY)]))
    63                 {
    64                     return false;
    65                 }
    66                 else
    67                 {
    68                     return true;
    69                 }
    70             }
    71         }
    72     }
    73 }
    74 

    测试页面:

    Default.aspx
     1 <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebTest._Default" %>
     2 
     3 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
     4 <html xmlns="http://www.w3.org/1999/xhtml">
     5 <head runat="server">
     6     <title>Untitled Page</title>
     7 </head>
     8 <body>
     9     <form id="form1" runat="server">
    10     <div>
    11         <asp:Label ID="Label1" runat="server"></asp:Label>
    12         <asp:Button ID="Button1" runat="server" Text="Button" />
    13     </div>
    14     </form>
    15 </body>
    16 </html>
    17 
    Default.aspx.cs
     1 using System;
     2 using System.Collections;
     3 using System.Configuration;
     4 using System.Data;
     5 using System.Linq;
     6 using System.Web;
     7 using System.Web.Security;
     8 using System.Web.UI;
     9 using System.Web.UI.HtmlControls;
    10 using System.Web.UI.WebControls;
    11 using System.Web.UI.WebControls.WebParts;
    12 using System.Xml.Linq;
    13 using DonkeyControl;
    14 
    15 
    16 namespace WebTest
    17 {
    18     public partial class _Default : BasePage
    19     {
    20         protected void Page_Load(object sender, EventArgs e)
    21         {
    22             if (this.IsRefreshed)
    23             {
    24                 Label1.Text = "刷新";
    25             }
    26             else
    27             {
    28                 Label1.Text = "正常postback";
    29             }
    30         }
    31     }
    32 }
    33 
  • 相关阅读:
    网站统计中的数据收集原理及实现
    启动hadoop报ERROR org.apache.hadoop.hdfs.server.namenode.FSImage: Failed to load image from FSImageFile
    淘宝(大数据库应用)--转载
    MapReduce作业的map task和reduce task调度参数
    Spark和Hadoop作业之间的区别
    分析MapReduce执行过程
    MapReduce框架Partitioner分区方法
    LVS+keepalived实现负载均衡
    Tomcat 详解
    linux Tomcat restart脚本简单版
  • 原文地址:https://www.cnblogs.com/nabber/p/1828480.html
Copyright © 2020-2023  润新知