zoukankan      html  css  js  c++  java
  • Asp.Net防止刷新重复提交数据小记

    Asp.Net防止刷新重复提交数据小记

    最近在用Asp.Net编写点东西时遇到个问题:即用户在提交表单后按刷新就会重复提交数据,即所谓的“刷新重复提交”的问题。在网上搜 一下,可以找到很多关于这方面的资料,其中有一篇是来自MSDN上的一种解决方法: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnvs05/html/BedrockASPNET.asp 它是通过重新定义 System.Web.UI.Page 类来实现加载页面时,是“刷新”、“后退”请求,还是正常请求,其他的页面则继承了自定义的这 个Page类。感觉他这个方法比较独特,有例子可以下载,有兴趣的可以研究研究。

    网上最多的解决此类问题的方法就是不保存缓存,即提交后表单上的数据不会被浏览器的缓存保存,如果此时再遇到刷新或者后退请求时, 就会显示“网页已过期”,数据也就不会重复提交了,这就起到了阻止刷新重复提交的效果。

    下面以简单的提交一篇帖子为例,介绍禁用缓存防止刷新重复提交的方法,表单数据包括“标题”和“正文”两个部分。

    以下是该方法的代码(post.aspx):

    //页面加载

    protected void Page_Load(object sender, EventArgs e)

    {

       //可以在页面加载时设置页面的缓存为“SetNoStore()”,即无缓存

       Response.Cache.SetNoStore();

       //Session中存储的变量“IsSubmit”是标记是否提交成功的

       if ((bool)Session["IsSubmit"])

       {

         //如果表单数据提交成功,就设“Session["IsSubmit"]”为false

         Session["IsSubmit"] = false;

         //显示提交成功信息

         ShowMsg.Text = " * 提交成功!";

       }

       else

         //否则的话(没有提交,或者是页面刷新),不显示任何信息

         ShowMsg.Text = "";

    }

    //提交按钮(btnOK)单击事件

    protected void btnOK_Click(object sender, EventArgs e)

    {

       if (txtTitle.Text.ToString().Trim() == "")

         //ShowMsg是用来显示提示信息的

         ShowMsg.Text = " * 标题不能为空!";

      else if (txtText.Text.ToString().Trim() == "")

         ShowMsg.Text = " * 内容不能为空!";

      else

       {

         //这里是将数据提交到数据库中,省略

         /*

         string sql = "insert into tab...values(...)";

         MyConn.ExecQuery(sql);

         */

         //提交成功后,设“Session["IsSubmit"]”为true

         Session["IsSubmit"] = true;

         //强制转换页面(不可少,否则刷新仍会重复提交,仍转到本页),

         通过页面的转换将缓存中的提交的数据都释放了,即提交的标单数据不会被保存到缓存里,

         如果后退的话,将会出现该页无法显示

         Response.Redirect("post.aspx");

      }

    }

    上面这个方法非常简单也很实用,推荐大家使用。

    下面是我自己研究出来的另一种方法,该方法不同于“不保存缓存的方法”,它是让浏览器保存所有页面缓存的。该方法通过随机码的方式 来判断是正常提交还是“刷新”或“后退”的。

    首先(提交页面是post.aspx)在 Session 中 增加变量 Rnd 用来存放随机码,同时在提交表单数据时不做处理,而是让页面转到 post.aspx?r=x,这里“x”等于Session["Rnd"],这个时候在页面加载时,通过判断r的值和Session["Rnd"]的值是否相同,如果相同就处理提 交的数据,否则即可认为是“刷新”或者是“后退”操作了,最后再次付给Session["Rnd"]一个随机码。

    以下是该方法代码(post.aspx):

    //获取随机码

    public class MyRnd

    {

       public static string Rnd()

       {

         //随机码是由 0-9 a-z A-Z 之间的数字或字母组成的

         //下面是生成的20位随机码

         //0..9 A..Z a..z

         //48-57 65-90 97-122

         string rst = "";

         Random rr = new Random();

         for (int i = 0; i < 20; i++)

         {

           int ir = 0;

           do

           {

             ir = rr.Next(123);

             if((ir >= 48) && (ir <= 57)) break;

             else if((ir >= 65) && (ir <= 90)) break;

             else if ((ir >= 97) && (ir <= 122)) break;

           }

           while (true);

           rst += ((char)ir).ToString();

           }

         return rst;

       }

    }

    //页面加载

    protected void Page_Load(object sender, EventArgs e)

    {

       //获取URL中请求的“r”值,如果“r”不存在则 r=""

       string r = "";

       if(Request.QueryString["r"] != null)

         r = Request.QueryString["r"].ToString().Trim();

       string t;

       //获取 “Session” 中的 “Rnd” 值,用于和“r”比较

       t = Session["Rnd"].ToString().Trim();

       //如果“r=t”则为提交操作,即可对表单的数据进行处理

      if(r == t)

      {

         if (txtTitle.Text.ToString().Trim() == "")

           ShowMsg.Text = " * 标题不能为空!";

         else if (txtText.Text.ToString().Trim() == "")

           ShowMsg.Text = " * 内容不能为空!";

         else      {

           //这里是将数据提交到数据库中,省略

           /*

           string sql = "insert into tab...values(...)";

           MyConn.ExecQuery(sql);

           */

           //提交成功后清空表单数据

           txtTitle.Text = "";

           txtText.Text = "";

           //显示提交成功信息

           ShowMsg.Text = " * 提交成功!";

         }

      }

       //否则可以认为是“刷新”或者“后退”操作

       else

       {

           txtTitle.Text = "";

           txtText.Text = "";

      }

      //最后要重新获得“Session["Rnd"]”的值,并将“btnOK.PostBackUrl”设为“Session["Rnd"]”的值

      Session["Rnd"] = MyRnd.Rnd();

      btnOK.PostBackUrl ="post.aspx?r=" + Session["Rnd"].ToString().Trim();

    }

    //这里提交按钮(btnOK)单击事件就不需要写任何代码了

    通过这种方法,每次加载页面时“Session["Rnd"]”都将得到一个新的值,而在刷新或后退时就不会得到相同的“r”和“t”值,数据也就 不会被重复提交,只有通过“btnOK”来提交的操作才会得到“r==t”,数据才会被提交处理的,通过判断随机码的方式来阻止刷新重复提交就 可以实现了。

    http://u.huoban001.com/space.php
  • 相关阅读:
    List of the best open source software applications
    Owin对Asp.net Web的扩展
    NSwag给api加上说明
    'workspace' in VS Code
    unable to find valid certification path to requested target
    JMeter的下载以及安装使用
    exception disappear when forgot to await an async method
    Filter execute order in asp.net web api
    记录web api的request以及response(即写log)
    asp.net web api的源码
  • 原文地址:https://www.cnblogs.com/zpq521/p/854631.html
Copyright © 2011-2022 走看看