Asp.Net防止多次提交数据(转)
Asp.Net防止多次提交数据 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结构框架学习网
//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 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结构框架学习网
<system.web> <httpModules> <add name="CSFramework_RefreshModule" type="CSFramework.BLL.RefreshModule"/> </httpModules>
参考文档:
Asp.Net防止恶意刷新网页 WebService架构提交数据-生成仅包含修改了字段的数据表 [原创]Asp.Net的GridView绑定空数据显示标题 使用SqlCommand提交数据:命令的Transaction 属性尚未初始化 提交数据时生成的SQL脚本便于实时跟踪 无DAL数据访问层提交单个表的数据 C/S系统快速开发平台采用ADO-Direct模式模拟数据提交流程 使用dalBaseDataDict类提交单表数据 C/S开发框架DAL层提交数据报错"外键值为空!"解决方案。 怎样将DAL层提交数据默认为系统数据库? C#使用Multipart form-data方式上传文件及提交其他数据 软件开发与设计 - BBS-电子布告栏系统-X3BLOG(ASP.NET开源多用户博客系统)数据库表结构 软件开发与设计 - BBS-电子布告栏系统-BBSGood论坛程序 ASP.NET版数据库表结构 CSFramework通用自动提交数据工具类(DbDataUpdate),支持MsSQL,MySQL,Oracle三种数据库 DbDataUpdate - 自动提交对象模型数据 - 常用数据类型测试
其它资料:
什么是C/S结构? | C/S框架核心组成部分 | C/S框架-WebService部署图 | C/S框架-权限管理 | C/S结构系统框架 - 5.1旗舰版介绍 | C/S结构系统框架 - 功能介绍 | C/S结构系统框架 - 产品列表 | C/S结构系统框架 - 应用展示(图) | 三层体系架构详解 | C/S架构轻量级快速开发框架 | C/S框架网客户案例 | WebApi快速开发框架 | C/S框架代码生成器 | 用户授权注册软件系统 | 版本自动升级软件 | 数据库底层应用框架 | CSFramework.CMS内容管理系统 | |