Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/37.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在ASP.Net中防止表单重新提交(不重定向到我自己)_Asp.net_Forms_Http_Code Behind - Fatal编程技术网

在ASP.Net中防止表单重新提交(不重定向到我自己)

在ASP.Net中防止表单重新提交(不重定向到我自己),asp.net,forms,http,code-behind,Asp.net,Forms,Http,Code Behind,我有一个带有表单元素()的母版页,一个带有按钮元素()的内容页,还有一个包含按钮点击功能的代码隐藏页 用户来到页面并单击按钮。代码隐藏代码(在服务器上)执行,更新数据库中的一些表。代码隐藏代码所做的最后一件事是在内容页上设置Span元素的InnerHTML,并显示成功或失败消息 这一切都很好。问题是,如果用户刷新页面,表单会重新提交,浏览器会询问用户是否真的想要这样做。如果用户的回答是肯定的,那么代码隐藏代码将重新执行,数据库将再次更新。如果用户的反应是否定的,那么什么也不会发生 重新执行代码背

我有一个带有表单元素(
)的母版页,一个带有按钮元素(
)的内容页,还有一个包含按钮点击功能的代码隐藏页

用户来到页面并单击按钮。代码隐藏代码(在服务器上)执行,更新数据库中的一些表。代码隐藏代码所做的最后一件事是在内容页上设置Span元素的InnerHTML,并显示成功或失败消息

这一切都很好。问题是,如果用户刷新页面,表单会重新提交,浏览器会询问用户是否真的想要这样做。如果用户的回答是肯定的,那么代码隐藏代码将重新执行,数据库将再次更新。如果用户的反应是否定的,那么什么也不会发生

重新执行代码背后的代码不是什么大问题。它不会伤害任何东西。但这并不是我想要的行为

我知道我可以使用Response.redirect()重定向回页面,但是用户永远看不到我的成功或失败消息。我应该提到,消息实际上不仅仅是“成功”或“失败”,否则我想我可以在重定向的查询字符串中添加一些内容

是否有办法从代码隐藏代码中重置表单元素,以便在用户刷新页面时不会重新提交表单

母版页

<%@ Master Language="C#" AutoEventWireup="true" CodeBehind="Site.master.cs" Inherits="IntuitSync.SiteMaster" %>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" xmlns:ipp="">
    <head runat="server">
    </head>
    <body>
        <form runat="server">
            <div runat="server" id="mainContetntDiv">
                <asp:ContentPlaceHolder ID="MainContent" runat="server" />
            </div>
        </form>
    </body>
</html>

非常感谢您提供的所有帮助。

问题在于您正在撰写一篇表单帖子,如果用户随后刷新页面,该帖子将执行它应该执行的操作:重新提交帖子。这是没有办法的。因此,您可以选择以下选项:

  • 重定向到确认页面,以某种方式将操作结果传递到确认页面(如果查询字符串/cookie/等不可行,通常从某个数据存储库重新加载)
  • 重定向到同一页面,但通过查询字符串参数传递成功消息(或者愚蠢地将其存储在session/ViewState/what have you愚蠢)
  • 不要过账,而是做一个表单get,因为看起来您并没有过账任何值,只是启动了某种服务器端处理。要做到这一点,只需将您的表单从post更改为get,或者只做一个链接。这里的危险在于,在任何get操作中,您都不应该执行任何改造性/破坏性操作
  • 注意:确保对任何和所有用户输入进行清理(始终将用户输入视为邪恶)

    你可能会对最后一个选项感到最高兴,但这一切都取决于“做一堆事情并将结果放入syncResults…”真正需要的是什么

    更新(几年后)


    虽然这应该是显而易见的,但对某些用户来说可能还不够明显:您永远不应该通过直接显示未经清理的“通过查询字符串参数发送的成功消息”来向XSS攻击敞开自己的大门。这些建议认为这是显而易见的,但回想起来,在这方面应该是明确的。

    我建议进入JASON路线

    在SyncToCloud.aspx.cs上

    [System.Web.Services.WebMethod]
        public static string updateSyncStatus()
        {
            /*
                    Do a bunch of stuff and put the results in syncResults which is a List.
                */
                SyncStatus.InnerHtml = string.Join("", syncResults.ToArray()); // I'd rather do this...
                //Response.Redirect(Request.Url.PathAndQuery, true);  // ...and not do this.
        }
    
    在SyncToCloud.aspx上

    function SyncStatus(){
                    $.ajax({
                                type: "POST",
                                async:true,
                                url: "syncToCloud.aspx/updateSyncStatus",
                                data: <if have anydata>,
                                contentType: "application/json; charset=utf-8",
                                dataType: "json",
                                success: function (msg) {
                                    if (msg.d == "Success") {                                    
                                        //Set message on some lable or do something
                                    } else {
                                        //Proceed to show message on wrong password
                                    }
                                } 
                            }); 
                }
    
    函数同步状态(){
    $.ajax({
    类型:“POST”,
    async:true,
    url:“syncToCloud.aspx/updateSyncStatus”,
    数据:,
    contentType:“应用程序/json;字符集=utf-8”,
    数据类型:“json”,
    成功:功能(msg){
    如果(msg.d==“成功”){
    //在某个标签上设置消息或执行某些操作
    }否则{
    //继续显示错误密码的消息
    }
    } 
    }); 
    }
    
    布顿上的标记

    <asp:Button ID="Button1" runat="server" OnClientClick="SyncStatus(); return false;" Text="Sync" />
    
    
    
    谢谢你,特德。是的,你是对的,我实际上没有发布表单中的任何值。如果由我决定,我会从母版页中删除表单元素,但我的理解是,如果没有表单元素,按钮将不会调用代码背后的代码。我更像是一个典型的ASP类型的人,而且我是ASP.NET的新手。我刚刚把它从Post改为Get,现在我在QueryString中得到了某种类型的_VIEWSTATE数据。毫无疑问,ASP.Net(因为没有更好的术语)必须这样做才能将所有部分保持在一起。我可能会转到选项1并停止尝试与之抗争。如果页面上不需要ViewState,请将其关闭。在你的情况下,你肯定不喜欢这个页面,所以在页面级别关闭它。为什么还要麻烦让它需要一个按钮呢?只需提供一个指向/a URL的链接,并将您的逻辑从“单击”按钮切换到“加载页面”…我不知道我可以关闭ViewState。我会调查的。为什么要按按钮?我希望用户能够在处理数据之前查看数据。该页面显示数据库中的数据,但需要同步到用户桌面版QuickBooks。例如,数据库中可能有10条新的客户记录需要与QuickBooks同步。syncResults将显示10条记录中有多少条成功同步(全部10条,10条中有9条,等等)。就我个人而言,我会有一个审查页面(查看未完成的记录)和一个确认页面(其中任何一个进程都可能有额外的记录潜入,并且需要非独立进程(标记为导入),或者更好的是,在审阅页面上进行处理,保存到数据存储,并在审阅页面上重新加载结果。我甚至不会问你打算如何让web应用程序与桌面QB同步。
    function SyncStatus(){
                    $.ajax({
                                type: "POST",
                                async:true,
                                url: "syncToCloud.aspx/updateSyncStatus",
                                data: <if have anydata>,
                                contentType: "application/json; charset=utf-8",
                                dataType: "json",
                                success: function (msg) {
                                    if (msg.d == "Success") {                                    
                                        //Set message on some lable or do something
                                    } else {
                                        //Proceed to show message on wrong password
                                    }
                                } 
                            }); 
                }
    
    <asp:Button ID="Button1" runat="server" OnClientClick="SyncStatus(); return false;" Text="Sync" />