2011-05-16 103 views
6

IN asp.net当我提交表单并刷新它时,数据又重新提交了? 有没有在C#中的方式来捕获页面加载页面刷新事件?页面刷新再次发射事件

+0

你刷新浏览器中按F5的页面?? – 2011-05-16 07:24:18

+0

是的,当我这样做时,先前触发的事件再次被触发 – Paras 2011-05-16 07:26:47

回答

7

ASP.NET不提供直接执行此操作的方法。

有一些技巧,而另一方面,为了避免重复提交:

提交后
  1. 重定向。这是最糟糕的一个。即使它避免了重复提交,但从用户的角度来看,它在现代Web应用程序中是不可接受的。

  2. 按表格提交的跟踪提交,每个会话。当用户第一次提交表格时,请在会话中记住这一点。如果发生了另一个提交,请尝试确定它是否必须被丢弃(在某些情况下,它不能;例如,如果我在StackOverflow上编辑我的答案一次,如果需要,我可以做两次)。

  3. 在第一次提交后禁用JavaScript提交。这样可以避免在用户双击提交按钮或第一次点击提交按钮时等待并认为表单未提交,从而第二次点击的情况。当然,不要依赖这一点:JavaScript可能被禁用,它可以在双击上工作,但不能在F5刷新上工作,并且在所有情况下这种技术都不是完全可靠的。

作为一个例子,我们试着实现第二个。

假设我们有一个评论框this.textBoxComment,它允许用户在博客的页面上添加新评论。提交是这样完成的:

private void Page_Load(object sender, System.EventArgs e) 
{ 
    if (this.IsPostBack) 
    { 
     string comment = this.ValidateCommentInput(this.textBoxComment.Text); 
     if (comment != null) 
     { 
      this.databaseContext.AddComment(comment); 
     } 
    } 
} 

如果用户点击两次,评论将被发布两次。

现在,让我们添加一些会话跟踪:

private void Page_Load(object sender, System.EventArgs e) 
{ 
    if (this.IsPostBack) 
    { 
     if (this.Session["commentAdded"] == null) 
     { 
      string comment = this.ValidateCommentInput(this.textBoxComment.Text); 
      if (comment != null) 
      { 
       this.databaseContext.AddComment(comment); 
       this.Session.Add("commentAdded", true); 
      } 
     } 
     else 
     { 
      // TODO: Inform the user that the comment cannot be submitted 
      // several times. 
     } 
    } 
} 

在这种情况下,用户将能够提交评论只有一次。其他评论将被自动丢弃。

问题是,用户可能想要添加评论到几个博客文章。我们有两种可能的方式来实现这一点。最简单的方法是在每个非回发请求上重置会话变量,但是这会允许用户在一个页面上提交帖子,加载另一个页面,而不是在第一个页面上点击刷新,从而提交评论两次,但不提交能够在第二页上添加评论。

private void Page_Load(object sender, System.EventArgs e) 
{ 
    if (this.IsPostBack) 
    { 
     if (this.Session["commentAdded"] == null) 
     { 
      string comment = this.ValidateCommentInput(this.textBoxComment.Text); 
      if (comment != null) 
      { 
       this.databaseContext.AddComment(comment); 
       this.Session.Add("commentAdded", true); 
      } 
     } 
     else 
     { 
      // TODO: Inform the user that the comment cannot be submitted 
      // several times. 
     } 
    } 
    else 
    { 
     this.Session.Remove("commentAdded"); 
    } 
} 

更高级的是在会话中跟踪提交评论的页面列表。

private void Page_Load(object sender, System.EventArgs e) 
{ 
    List<string> commentsTrack = this.Session["commentAdded"] as List<string>; 
    string blogPostId = this.ValidatePostId(this.Request.QueryString["id"]); 
    if (blogPostId != null) 
    { 
     if (this.IsPostBack) 
     { 
      this.AddComment(commentsTrack); 
     } 
     else 
     { 
      if (commentsTrack != null && commentsTrack.Contains(blogPostId)) 
      { 
       commentsTrack.Remove(blogPostId); 
      } 
     } 
    } 
} 

private void AddComment(List<string> commentsTrack) 
{ 
    if (commentsTrack == null || !commentsTrack.Contains(blogPostId)) 
    { 
     string comment = this.ValidateCommentInput(this.textBoxComment.Text); 
     if (comment != null) 
     { 
      this.databaseContext.AddComment(comment); 
      if (commentsTrack == null) 
      { 
       commentsTrack = new List<string>(); 
      } 

      commentsTrack.Add(blogPostId); 
      this.Session["commentAdded"] = commentsTrack; 
     } 
    } 
    else 
    { 
     // TODO: Inform the user that the comment cannot be submitted 
     // several times. 
    } 
} 
+0

我认为这不是问题,因为他在浏览器中刷新页面。 – 2011-05-16 07:25:06

+0

@Muhammad Akhtar:是的,谢谢,我完全误解了这个问题。现在编辑答案。 – 2011-05-16 07:33:01

+0

只是一个想法。如果我们将其重定向到同一页面,该怎么办?接受的方法与否? – Malik 2011-06-15 09:35:10

1

,你可以,如果它在你的心中的任何一点,使页面刷新自身提交表单后自动重新加载去除文本框等所有文本您可以通过添加以下代码做到这一点的页面 - >Page.Redirect(Request.RawUrl);在提交方法的底部。

-1

例如: 如果您点击'按钮'系统将捕获事件'button_click'。 如果刷新页面,系统将再次执行相同的事件。 穿上吨有这个问题,在事件插入: 了你的活动

private void button_click(object sender, System.EventArgs e) 
{ 
    button.Enabled =false; 
    button.Enabled =true; 
} 

是你的意思?

+0

与你的这个答案的其他副本一样,这不是问题所在。 – 2013-10-23 13:58:35

0

我得到同样的问题,我解决了会话跟踪。 而我认为这是容易较少耗时方式来解决这个问题。