| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 628 人关注过本帖
标题:使用HttpModule来禁用Web表单重复提交
只看楼主 加入收藏
saiyo55
Rank: 1
等 级:新手上路
帖 子:5
专家分:0
注 册:2010-8-5
结帖率:0
收藏
 问题点数:0 回复次数:0 
使用HttpModule来禁用Web表单重复提交
在网速慢或者网站反应慢的情况下,如果提交表单需要超过5秒的时间还未提交成功,多数人会重新点击提交。这样不仅造成错误的数据,还会加剧服务器的压力。

    通过使用HttpModule,我们可以在表单处理前,检测一些标志,从而防止用户重复提交数据,再通过一些接口,让用户自己来处理重复提交时,应该如何告诉用户。

    通过使用HttpModule,我们也可以在客户端表单提交时,使用DIV覆盖住表单,从UI层防止用户再次单击提交(用户直接F5管不了)。

    这种方法使用简单,直接把脚本和图片放在指定的目录中,然后在Web.config中添加Module
 
     <httpModules>
            <!--防止重复提交 LOG记录MODULE -->
            <add name="NonReduplicatePostModule" type="tests.NonReduplicatePostModule,test"/>
    </httpModules>
    下面是实现代码:
     /// NonReduplicatePostModule 的摘要说明。
    /// </summary>
    public class NonReduplicatePostModule : System.Web.IHttpModule
    {
        private static ILog log  = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
        private const string hiddenFileName = "__NonReduplicatePostModule__";
        private const string maskdivScriptRelativeUrl = "~/js/maskDiv.js";
        private const string onformSubmit = "Evlon.MaskDiv.Instance.show();";
        private HttpApplication context = null;
        #region IHttpModule 成员
        public void Init(HttpApplication context)
        {
            this.context = context;
            this.context.PreRequestHandlerExecute+=new EventHandler(context_PreRequestHandlerExecute);
        }

        public void Dispose()
        {
            this.context.PreRequestHandlerExecute-=new EventHandler(context_PreRequestHandlerExecute);
        }
        #endregion
        private void context_PreRequestHandlerExecute(object sender, EventArgs e)
        {
            HttpApplication webApp = sender as HttpApplication;
            if(webApp != null)
            {
                //已经处理过,提示用户不要重复提交
                Page page = webApp.Context.Handler as Page;
                if(page != null)
                {
                    page.PreRender+=new EventHandler(page_PreRender);
                    
                    //找到Page,添加时间
                    if(webApp.Request.Form[hiddenFileName] != null)
                    {
                        string flag = webApp.Request.Form[hiddenFileName].ToString();
                        if(webApp.Context.Cache.Get(flag) != null)
                        {
                            log.Debug("found  reduplicate post");
                            if(page is IReduplicatePostHandler)
                            {
                                webApp.Context.Handler = new ReduplicatePostHandler((IReduplicatePostHandler)page);
                            }
                            else
                            {
                                webApp.Context.Handler = new ReduplicatePostHandler();
                            }
                        }
                        else
                        {
                            //放进缓存中,表示已经被处理过,在一分钟后自动移聊(可再次提交)
                            webApp.Context.Cache.Add(flag,DateTime.Now,null,System.Web.Caching.Cache.NoAbsoluteExpiration,TimeSpan.FromMinutes(1),System.Web.Caching.CacheItemPriority.Normal,null);
                        }
                    }
                }
            }

        }

 

        private void page_PreRender(object sender, EventArgs e)
        {
            Page page = sender as Page;
            if(page != null)
            {
                //找到Page,添加时间
                page.RegisterHiddenField(hiddenFileName,string.Format("{0}_{1}_{2}",page.Session.SessionID.GetHashCode(), page.GetType().GetHashCode(), DateTime.Now.Ticks));
                //表单UI显示 MASKDIV
                page.RegisterClientScriptBlock("maskdiv_include","<script type='text/javascript' src='" + page.ResolveUrl(maskdivScriptRelativeUrl) + "' ></script>");
                page.RegisterOnSubmitStatement("maskdiv", onformSubmit);
            }

        }
    }

    public interface IReduplicatePostHandler
    {
        void OnReduplicatePost(HttpContext context, EventArgs e);
    }

    internal class ReduplicatePostHandler : IHttpHandler
    {
        private IReduplicatePostHandler handler = null;
        internal ReduplicatePostHandler(IReduplicatePostHandler handler)
        {
            this.handler = handler;
        }

        internal ReduplicatePostHandler()
        {
        
        }

        #region IHttpHandler 成员

        public void ProcessRequest(HttpContext context)
        {
            if(handler != null)
            {
                handler.OnReduplicatePost(context,new EventArgs());
            }
            else
            {
                context.Response.Write("不要重复提交");
            }
        }

        public bool IsReusable
        {
            get
            {
                // TODO:  添加 ReduplicatePostHandler.IsReusable getter 实现
                return false;
            }
        }

        #endregion

    }

 

     用到的JS文件:/js/MaskDIV.js

Code
Evlon = {};
Evlon.MaskDiv = function()
{
    var div = window.document.createElement("DIV");
    div.style.position = "absolute";
    div.style.top = "0px";
    div.style.left = "0px";
    div.style.width = '100%';//document.body.scrollWidth + 'px';
    div.style.height = '100%'; //document.body.scrollHeight + 'px';
    div.style.backgroundColor = "white";
    div.style.zIndex = 999;
    div.style.filter = "Alpha(style=0,opacity=50)";
    div.style.opacity="0.50";
    this.divMask = div;
    div = window.document.createElement("DIV");
    div.style.position = "absolute";
    div.style.top = "0px";
    div.style.left = "0px";
    div.style.width = '100%';//document.body.scrollWidth + 'px';
    div.style.height = '100%'; //document.body.scrollHeight + 'px';
    div.style.zIndex = 1000;
    this.divTooltip = div;
    this.show = function()
    {
        //创建半透明DIV
        window.__maskDiv__ = document.body.insertAdjacentElement('afterBegin',this.divMask);
        
        //创建提示DIV
        window.__maskDivText__ = document.body.insertAdjacentElement('afterBegin',this.divTooltip);
        window.__maskDivText__.innerHTML = "<table style='border-collapse:collapse;border-width:0px;width:100%;height:100%;'0><tr height='38%'><td></td></tr><tr><td align='center' valign='top'>" +
                    "<table style='border-collapse:collapse;border:solid 1px yellow;'><tr><td align='right'><img width='20' height='20' src='image/loading.gif' usesrc='image/loading.gif' onerror='this.src= this.usesrc = \"../\" + this.usesrc'/></td>" +
                    "<td align='left'><span style = 'filter:alpha(opacity=100);background-color:#ccc;font-size:20px'>提交中.</span></td></tr></table>" +
                    "</td></tr></table>";
    }
    this.hide = function()
    {
        if(window.__maskDiv__ != null)
        {
            document.body.removeChild(window.__maskDiv__);
            window.__maskDiv__  = null;
        }
        if(window.__maskDivText__ != null)
        {
            window.__maskDivText__.innerHTML = '';
            document.body.removeChild(window.__maskDivText__);
            window.__maskDivText__  = null;
        }
    }
}
Evlon.MaskDiv.Instance = new Evlon.MaskDiv();
window.showModalDialogMask = function(sURL , vArguments, sFeatures)
{
    var sign = window.showModalDialog(sURL , vArguments, sFeatures);
    if(sign != "" && sign != null)
    {
        //创建半透明DIV
        Evlon.MaskDiv.Instance.show();
        
    }
    return null;
    //return sign;
}
 

搜索更多相关主题的帖子: HttpModule 表单 Web 
2010-10-26 16:36
快速回复:使用HttpModule来禁用Web表单重复提交
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.029310 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved