Asp.Net防止多次提交数据(转)
Asp.Net防止多次提交数据
RefreshAction类:
public static class RefreshAction
{
// 常量
//服务端票证key
public const string LastRefreshTicketEntry = "__LASTREFRESHTICKET"; //客户端票证key
public const string CurrentRefreshTicketEntry = "__CURRENTREFRESHTICKET"; //用来保存是否是重复刷新的属性的key
public const string PageRefreshEntry = "IsPageRefresh"; // 检测F5按钮是否被按下
public static void Check(HttpContext ctx)
{
//初始化服务端票证
EnsureRefreshTicket(ctx); //从Session里读取上一次提供的票证
int lastTicket = GetLastRefreshTicket(ctx); //从请求里的隐藏域里读取当前页面的票证
int thisTicket = GetCurrentRefreshTicket(ctx); // 对比两个票证
if (thisTicket != lastTicket || (thisTicket == lastTicket && thisTicket == 0))
{
//如果当前的票证值大于上一次的票证值 或者
//当前票证值等于上一次票证值,并且当前票证值为0(这是第一次刷新)
//那么更新Session里上一次的票证值为当前票证值
UpdateLastRefreshTicket(ctx, thisTicket); //设置当前页是否重复刷新属性为false
ctx.Items[PageRefreshEntry] = false;
}
else
{
//设置当前页是否重复刷新属性为true;
ctx.Items[PageRefreshEntry] = true;
}
}
//确认上一次的票证不为空值
private static void EnsureRefreshTicket(HttpContext ctx)
{
// Initialize the session slots for the page (Ticket) and the module (LastTicketServed)
//初始化Session的最后一次票证值
if (ctx.Session[LastRefreshTicketEntry] == null)
ctx.Session[LastRefreshTicketEntry] = 0;
}
//从Session里得到上一次请求的票证值
private static int GetLastRefreshTicket(HttpContext ctx)
{ //返回Session里保存的上一次票证值
return Convert.ToInt32(ctx.Session[LastRefreshTicketEntry]);
}
//从当前请求里的到隐藏域里保存的当前票证值
private static int GetCurrentRefreshTicket(HttpContext ctx)
{
return Convert.ToInt32(ctx.Request[CurrentRefreshTicketEntry]);
}
// 将当前的票证值保存到Session里的上一次刷新的票证值
private static void UpdateLastRefreshTicket(HttpContext ctx, int ticket)
{
ctx.Session[LastRefreshTicketEntry] = ticket;
}
}
// 来源:www.CSFramework.com, C/S结构框架学习网
{
// 常量
//服务端票证key
public const string LastRefreshTicketEntry = "__LASTREFRESHTICKET"; //客户端票证key
public const string CurrentRefreshTicketEntry = "__CURRENTREFRESHTICKET"; //用来保存是否是重复刷新的属性的key
public const string PageRefreshEntry = "IsPageRefresh"; // 检测F5按钮是否被按下
public static void Check(HttpContext ctx)
{
//初始化服务端票证
EnsureRefreshTicket(ctx); //从Session里读取上一次提供的票证
int lastTicket = GetLastRefreshTicket(ctx); //从请求里的隐藏域里读取当前页面的票证
int thisTicket = GetCurrentRefreshTicket(ctx); // 对比两个票证
if (thisTicket != lastTicket || (thisTicket == lastTicket && thisTicket == 0))
{
//如果当前的票证值大于上一次的票证值 或者
//当前票证值等于上一次票证值,并且当前票证值为0(这是第一次刷新)
//那么更新Session里上一次的票证值为当前票证值
UpdateLastRefreshTicket(ctx, thisTicket); //设置当前页是否重复刷新属性为false
ctx.Items[PageRefreshEntry] = false;
}
else
{
//设置当前页是否重复刷新属性为true;
ctx.Items[PageRefreshEntry] = true;
}
}
//确认上一次的票证不为空值
private static void EnsureRefreshTicket(HttpContext ctx)
{
// Initialize the session slots for the page (Ticket) and the module (LastTicketServed)
//初始化Session的最后一次票证值
if (ctx.Session[LastRefreshTicketEntry] == null)
ctx.Session[LastRefreshTicketEntry] = 0;
}
//从Session里得到上一次请求的票证值
private static int GetLastRefreshTicket(HttpContext ctx)
{ //返回Session里保存的上一次票证值
return Convert.ToInt32(ctx.Session[LastRefreshTicketEntry]);
}
//从当前请求里的到隐藏域里保存的当前票证值
private static int GetCurrentRefreshTicket(HttpContext ctx)
{
return Convert.ToInt32(ctx.Request[CurrentRefreshTicketEntry]);
}
// 将当前的票证值保存到Session里的上一次刷新的票证值
private static void UpdateLastRefreshTicket(HttpContext ctx, int ticket)
{
ctx.Session[LastRefreshTicketEntry] = ticket;
}
}
// 来源:www.CSFramework.com, C/S结构框架学习网
RefreshModule 类:
//Provides module initialization and disposal events to the implementing class
public class RefreshModule : IHttpModule
{
//初始化模块
public void Init(HttpApplication app)
{ // Register for pipeline events
//注册请求关联状态时的事件处理器,就是说当一个请求到达服务器,
//那么首先触发这个事件,由OnAcquireRqeustState事件处理
app.AcquireRequestState = new EventHandler(this.OnAcquireRequestState);
}
// IHttpModule::Dispose
public void Dispose() { }
//判断是否是F5或前进/后退操作
private void OnAcquireRequestState(object sender, EventArgs e)
{
//得到访问的HTTP上下文
HttpApplication app = (HttpApplication)sender;
HttpContext ctx = app.Context; //检查是否是F5操作
if (ctx != null && ctx.Session != null)
RefreshAction.Check(ctx);
return;
}
}
// 来源:www.CSFramework.com, C/S结构框架学习网
public class RefreshModule : IHttpModule
{
//初始化模块
public void Init(HttpApplication app)
{ // Register for pipeline events
//注册请求关联状态时的事件处理器,就是说当一个请求到达服务器,
//那么首先触发这个事件,由OnAcquireRqeustState事件处理
app.AcquireRequestState = new EventHandler(this.OnAcquireRequestState);
}
// IHttpModule::Dispose
public void Dispose() { }
//判断是否是F5或前进/后退操作
private void OnAcquireRequestState(object sender, EventArgs e)
{
//得到访问的HTTP上下文
HttpApplication app = (HttpApplication)sender;
HttpContext ctx = app.Context; //检查是否是F5操作
if (ctx != null && ctx.Session != null)
RefreshAction.Check(ctx);
return;
}
}
// 来源:www.CSFramework.com, C/S结构框架学习网
定义一个基类,所有提交数据的页面继承:SubmitOncePage
public class SubmitOncePage : PageBaseRefreshCounter
{
#region Constants
// 常量
public const string RefreshTicketCounter = "RefreshTicketCounter";
#endregion
// Ctor
public SubmitOncePage()
{
// Register a PreRender handler
//注册页面呈现前的事件处理器
this.PreRender = new EventHandler(RefreshPage_PreRender);
}
//标志页面是否按F5进行重复刷新的标志属性
public bool IsPageRefresh
{
get
{
object o = HttpContext.Current.Items[RefreshAction.PageRefreshEntry];
if (o == null)
return false;
return (bool)o;
}
set
{
object o = HttpContext.Current.Items[RefreshAction.PageRefreshEntry];
if (o != null)
HttpContext.Current.Items[RefreshAction.PageRefreshEntry] = false;
}
}
//增加刷新票证的内部计数器
public void TrackRefreshState()
{ //初始化刷新计数器
InitRefreshState();
//将刷新计数器加1,然后放进Session
int ticket = Convert.ToInt32(Session[RefreshTicketCounter]) 1;
Session[RefreshTicketCounter] = ticket;
}
#region Private Members
// Create the hidden field to store the current request ticket
//创建隐藏域来保存当前请求的票证值
private void SaveRefreshState()
{
//将票证计数器的值加1,然后将此值注册到当前票证隐藏域中
int ticket = Convert.ToInt32(Session[RefreshTicketCounter]) 1;
this.ClientScript.RegisterHiddenField(RefreshAction.CurrentRefreshTicketEntry, ticket.ToString());
}
//初始化刷新计数器
private void InitRefreshState()
{
if (Session[RefreshTicketCounter] == null)
Session[RefreshTicketCounter] = 0;
}
// PreRender事件处理器
private void RefreshPage_PreRender(object sender, EventArgs e)
{
//在页面呈现之前就保存票证值到隐藏域
SaveRefreshState();
}
#endregion
}
// 来源:www.CSFramework.com, C/S结构框架学习网
{
#region Constants
// 常量
public const string RefreshTicketCounter = "RefreshTicketCounter";
#endregion
// Ctor
public SubmitOncePage()
{
// Register a PreRender handler
//注册页面呈现前的事件处理器
this.PreRender = new EventHandler(RefreshPage_PreRender);
}
//标志页面是否按F5进行重复刷新的标志属性
public bool IsPageRefresh
{
get
{
object o = HttpContext.Current.Items[RefreshAction.PageRefreshEntry];
if (o == null)
return false;
return (bool)o;
}
set
{
object o = HttpContext.Current.Items[RefreshAction.PageRefreshEntry];
if (o != null)
HttpContext.Current.Items[RefreshAction.PageRefreshEntry] = false;
}
}
//增加刷新票证的内部计数器
public void TrackRefreshState()
{ //初始化刷新计数器
InitRefreshState();
//将刷新计数器加1,然后放进Session
int ticket = Convert.ToInt32(Session[RefreshTicketCounter]) 1;
Session[RefreshTicketCounter] = ticket;
}
#region Private Members
// Create the hidden field to store the current request ticket
//创建隐藏域来保存当前请求的票证值
private void SaveRefreshState()
{
//将票证计数器的值加1,然后将此值注册到当前票证隐藏域中
int ticket = Convert.ToInt32(Session[RefreshTicketCounter]) 1;
this.ClientScript.RegisterHiddenField(RefreshAction.CurrentRefreshTicketEntry, ticket.ToString());
}
//初始化刷新计数器
private void InitRefreshState()
{
if (Session[RefreshTicketCounter] == null)
Session[RefreshTicketCounter] = 0;
}
// PreRender事件处理器
private void RefreshPage_PreRender(object sender, EventArgs e)
{
//在页面呈现之前就保存票证值到隐藏域
SaveRefreshState();
}
#endregion
}
// 来源:www.CSFramework.com, C/S结构框架学习网
最后在Web.Config文件内定义一个<httpModules>
<system.web>
<httpModules>
<add name="CSFramework_RefreshModule" type="CSFramework.BLL.RefreshModule"/>
</httpModules>
版权声明:本文为开发框架文库发布内容,转载请附上原文出处连接
NewDoc
C/S框架网