最近学了下HttpModule的内容,可用来解决这个问题.
这里利用HttpModule在页面请求之前,做一些操作,用一些标记标识每个请求的页面,程序如下,相互学习下.
首先有个类继承IHttpModule
1
public class NoRepeatOperModule : IHttpModule2

{3

/**//// <summary>4
/// 保存访问的页面记录,以页面路径为key, 标号为value5
/// </summary>6
static Hashtable historyRequest = null;7

8

/**//// <summary>9
/// 请求路径10
/// </summary>11
private string RequestPath12

{13
get14

{15
return HttpContext.Current.Request.Path;16
}17
}18

19

IHttpModule 成员#region IHttpModule 成员20

21
public void Dispose()22

{23
//throw new Exception("The method or operation is not implemented.");24
}25

26
public void Init(HttpApplication context)27

{28
if (historyRequest == null)29

{30
historyRequest = new Hashtable();31
}32

33
context.BeginRequest += delegate(object sender, EventArgs e)34

{35
int lastTicket = GetLastTicket();36
int currentTicket = GetCurrentTicket(lastTicket);37

38
// 比较当前标号和上一个的标号,判断页面请求是否来源于刷新操作39
// 当前标号大于上一个标号 或初次请求都属于新的页面40
if (currentTicket > lastTicket || (lastTicket == currentTicket && currentTicket == 0))41

{42
// 标记并保存页面请求是否来源于刷新的bool值43
HttpContext.Current.Items[RequestPath + "_IsRefreshed"] = false;44
historyRequest[RequestPath] = currentTicket;45
}46
else47

{48
HttpContext.Current.Items[RequestPath + "_IsRefreshed"] = true;49
}50
};51
}52

53
#endregion54

55

/**//// <summary>56
/// 获取某页面的上一个标号57
/// </summary>58
/// <returns></returns>59
private int GetLastTicket()60

{61
if (!historyRequest.ContainsKey(RequestPath))62

{63
return 0;64
}65

66
return int.Parse(historyRequest[RequestPath].ToString());67
}68

69

/**//// <summary>70
/// 获取页面的当前标号71
/// </summary>72
/// <param name="lastTicket">上一个标号</param>73
/// <returns></returns>74
private int GetCurrentTicket(int lastTicket)75

{76
int ticket;77
// CurrentTicket 为页面的隐藏域的内容78
string currentTicket = HttpContext.Current.Request["CurrentTicket"];79
if (currentTicket == null)80

{81
ticket = lastTicket;82
}83
else84

{85
ticket = int.Parse(currentTicket);86
}87

88
// 保存页面的下一个标号89
HttpContext.Current.Items[RequestPath + "_NextTicket"] = ticket + 1;90
return ticket;91
}92
}第二步,在web.config中配置自定义的HttpModule
1
<system.web>2
<httpModules>3
<add name="NoRepeatOperModule" type="AspAdvance1.NoRepeatOperModule, AspAdvance1"/>4
</httpModules>5
</system.web>最后还要在asp.cs文件中处理如下,加个属性IsRefreshed,重写基类的OnPreRenderComplete,最后调用在btnTest_Click
其实可以吧以下作为自定义的Page类,其他页面继承即可
1
public partial class _Default : System.Web.UI.Page2

{3

/**//// <summary>4
/// 页面请求是否来源于页面刷新5
/// </summary>6
private bool IsRefreshed7

{8
get9

{10
string requestPath = HttpContext.Current.Request.Path;11
return (bool)HttpContext.Current.Items[requestPath + "_IsRefreshed"];12
}13
}14

15

/**//// <summary>16
/// 重写OnPreRenderComplete,生成隐藏域CurrentTicket17
/// </summary>18
/// <param name="e"></param>19
protected override void OnPreRenderComplete(EventArgs e)20

{21
base.OnPreRenderComplete(e);22
string requestPath = HttpContext.Current.Request.Path;23
int ticket = int.Parse(HttpContext.Current.Items[requestPath + "_NextTicket"].ToString());24
ClientScript.RegisterHiddenField("CurrentTicket", ticket.ToString());25
}26

27
protected void btnTest_Click(object sender, EventArgs e)28

{29
// 根据IsRefreshed 判断页面请求是否来源于刷新来 判断是否进行操作30
if (!IsRefreshed)31

{32
using (StreamWriter sw = new StreamWriter("E:\\test.txt", true))33

{34
sw.WriteLine(DateTime.Now.ToString());35
}36
}37
}38
}点击btnTest之后会写入一行,此时页面重新生成,点刷新或回退,再点"重试",将不会重复原来的操作.