ASP.NET 如何避免页面重新整理时重复送出

cyblz1 2010-06-06 11:43:50
有些使用者的行为真是令人猜不透…,开网页有事没事就来给你 Refresh 一下,这个动作看似无害,但是在刚执行过 Submit 的情况下,Refresh 网页会造成重复执行,这也是为什么在各大购物网站的交易付款动作,都会提示「不要关闭网页或重新整理避免造成交易失败或重复交易」这一类的讯息,但根据经验,就算在网页上提出警告了,仍有为数不少的使用者依然会 Refresh 网页。


本文来自:a6站长网(http://www.a6zzw.com) 详细出处参考:http://www.a6zzw.com/12host/2837.html
...全文
144 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
我写过一个Page的父类用在我的网站里,有个“副作用”可以防止刷新,贴在这里:
using System;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
using System.Threading;
using System.Web.UI;

public class XVPage : Page
{
static private DirectoryInfo _Dir;

private static DirectoryInfo Dir
{
get
{
if (_Dir == null)
{
_Dir = new DirectoryInfo(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "App_Data"));
if (!_Dir.Exists)
_Dir.Create();
_Dir = new DirectoryInfo(Path.Combine(_Dir.FullName, "ViewState"));
if (!_Dir.Exists)
_Dir.Create();
}
return _Dir;
}
}

protected override object LoadPageStateFromPersistenceMedium()
{
PageStatePersister ps = this.PageStatePersister;
ps.Load();
if (ps.ControlState != null)
ps.ControlState = 反序列化对象((string)ps.ControlState);
if (ps.ViewState != null)
ps.ViewState = 反序列化对象((string)ps.ViewState);
return new Pair(ps.ControlState, ps.ViewState);
}

protected override void SavePageStateToPersistenceMedium(object state)
{
PageStatePersister ps = this.PageStatePersister;
if (state is Pair)
{
ps.ControlState = ((Pair)state).First;
ps.ViewState = ((Pair)state).Second;
}
else
ps.ViewState = state;
if (ps.ControlState != null)
ps.ControlState = 序列化对象(ps.ControlState);
if (ps.ViewState != null)
ps.ViewState = 序列化对象(ps.ViewState);
ps.Save();
}

private object 反序列化对象(string stateID)
{
if (stateID == null)
return null;

object state = Cache[stateID];
string fname = Path.Combine(Dir.FullName, stateID);
if (state == null)
using (var stream = File.OpenRead(fname))
state = new BinaryFormatter().Deserialize(stream);
this.Page.SaveStateComplete += (s, e) => //当发生异常时,此方法不会执行,因此可以保证不会误删ViewState文件
{
Cache.Remove(stateID);
File.Delete(fname); //这个方法恰好可以禁止浏览器端的“刷新”。
};
return state;
}

static long seed1 = DateTime.Now.Ticks;
static ulong seed2 = 0;

private string 序列化对象(object obj)
{
string stateID = seed1.ToString() + "_" + (seed2++).ToString();
Cache.Insert(stateID, obj, null, DateTime.Now.AddMinutes(5), TimeSpan.Zero);
var stream = new MemoryStream();
new BinaryFormatter().Serialize(stream, obj);
ThreadPool.QueueUserWorkItem(h =>
{
File.WriteAllBytes(Path.Combine(Dir.FullName, stateID), stream.ToArray());
});
return stateID;
}

static XVPage()
{
var et = DateTime.Now.AddMinutes(-30);
Dir.GetFiles()
.Where(f => f.LastAccessTime < et)
.ToList()
.ForEach(f =>
{
try
{
f.Delete();
}
catch { }
});
}
}
你可以在语句 File.Delete(fname); 那一行写代码首先判断fname是否存在,如果不存在则转入自定义的“抛出刷新异常”的流程。
  • 打赏
  • 举报
回复
不大了解 帮顶啦.
whatisma 2010-06-07
  • 打赏
  • 举报
回复
mark。。。
naoxin219 2010-06-07
  • 打赏
  • 举报
回复
在学习
加油馒头 2010-06-07
  • 打赏
  • 举报
回复
记录下 状态信息,如果是刷新则 不允许
  • 打赏
  • 举报
回复
不论是重定向还是连接到其它页面,总之是用在不打算继续交互操作(从而不需要状态)的页面上,而交互操作则无法使用了!
无爱大叔 2010-06-06
  • 打赏
  • 举报
回复
方法很多了,楼上是一种。
也可以用Respone.Redirect(url)或session来控制

还可以在页面加个空链接执行LinkButton_Click方法,我个人比较推荐此方法:
在执行完保存(或更新之类)的操作后再执行LinkButton_Click方法。
PandaIT 2010-06-06
  • 打赏
  • 举报
回复
Respone.Redirect(url) 处理完用重定向来做!

if(Request.Headers["Accept"] == "*/*")
{
//也可试试这种方法
}

62,074

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧