确认表单重新提交浏览器弹出窗口重复记录

时间:2014-10-14 09:48:50

标签: c# asp.net postback

我正在开发一个存在问题的应用程序。当我单击提交按钮时,数据将插入到数据库中。但是当我按ctrl + R或f5时会出现一个chrome或IE弹出窗口,其中显示确认表单重新提交。当我点击继续时,记录将复制到数据库中。

我的问题是,

  1. 为什么会弹出这个弹出窗口?因为回发?如果因为回发那么我的代码有任何问题,或者在进行回发时它会发生在每个人身上。

  2. 使用mvc会完全解决这个问题吗?

  3. 我的代码:

    protected void btnSubmit_Click(object sender, EventArgs e)
            {
                if (Page.IsValid)
                {
                    paramArray = new string[9];
                    paramValues = new object[9];
                    try
                    {
                        paramArray[0] = "@AccountNumber";
                        paramValues[0] = (!string.IsNullOrEmpty(this.txtAccountNumber.Value) ? this.txtAccountNumber.Value.Trim() : string.Empty);
    
                        paramArray[1] = "@OpeningBalance";
                        paramValues[1] = (!string.IsNullOrEmpty(this.txtOpeningBalance.Value) ? Convert.ToDouble(this.txtOpeningBalance.Value.Trim()) : 0.00);
    
                        paramArray[2] = "@ClosingBalance";
                        paramValues[2] = (!string.IsNullOrEmpty(this.txtClosingBalance.Value) ? Convert.ToDouble(this.txtClosingBalance.Value.Trim()) : 0.00);
    
                        paramArray[3] = "@PaymentMode";
                        paramValues[3] = this.ddlModeofPayment.Value;
    
                        paramArray[4] = "@PaymentDate";
                        paramValues[4] = this.dtPaymentDate.Value;
    
                        paramArray[5] = "@PaymentAmount";
                        paramValues[5] = (!string.IsNullOrEmpty(this.txtPaymentAmount.Value) ? Convert.ToDouble(this.txtPaymentAmount.Value.Trim()) : 0.00);
    
                        paramArray[6] = "@isAccount";
                        paramValues[6] = true;
    
                        paramArray[7] = "@UserId";
                        paramValues[7] = (!string.IsNullOrEmpty(this.User.Identity.Name.Remove(0, 7)) ? this.User.Identity.Name.Remove(0, 7) : string.Empty);
    
                        paramArray[8] = "@isProcessed";
                        paramValues[8] = default(bool);
    
                        var success = herlperUtility.ExecuteParameterizedQuery("{CALL asp_sp_InsertPayment(?,?,?,?,?,?,?,?,?)}", paramArray, paramValues);
    
                        if (!string.IsNullOrEmpty(success.Rows[0]["ReferenceNumber"].ToString()))
                        {
                            this.Page.Response.Redirect("AccountPaymentScreen.aspx?flag=1");
                            divSuccess.Attributes.Add("style", "display:block");
                            this.refId.InnerText = "<b>Success!</b> The " + success.Rows[0]["ReferenceNumber"] + " has been successfuly forwarded to the supervisor";
    
                            this.ClearFields();
                        }
    
                        else
                        {
                            this.divFailure.Attributes.Add("style", "display:block");
                        }
                    }
                    catch (Exception ex)
                    {
                        this.divFailure.Attributes.Add("style", "display:block");
                        this.divFailure.InnerText = ex.Message;
                    }
                }
    

1 个答案:

答案 0 :(得分:2)

解决方法是遵循Post-Redirect-Get pattern。这意味着在执行某种事务活动的HTTP POST之后,您将客户端重定向到HTTP GET。

以一种非常简单的思维方式:GET不应修改任何内容,而POST则可以进行更改。

例如,请考虑以下工作流程。

  1. 用户按购物车页面上的提交(HTTP POST)。
  2. 您确认信用卡有效,如果是,则收取费用 帐户并设置您的仓库活动
  3. 您会显示确认订单的屏幕。
  4. 如果一切顺利且您没有重定向客户端(例如,您显示一个带有成功消息的面板并隐藏购物车)并且客户端按下刷新,则会重新提交订单,这可能不适合其他任何人比应收账款。

    遵循PRG模式,在提交订单后,您将重定向到GET页面(可能在查询字符串中使用订单ID,以便您可以通过某种方式引用订单)并显示您的成功消息。此页面可以根据客户的需要进行多次刷新(附加可加入书签的奖励),对后端系统或客户的钱包没有任何副作用。

    值得注意的是,你不必对此充满狂热。在此示例中,如果信用卡验证失败,您可以选择仅显示POST操作的结果并在页面上切换错误消息。如果用户刷新页面,验证将运行并再次失败,但不会对您的后端系统进行任何更改。

    对于MVC而言 - 它并不是那么容易实现这一点(它是),而是你最终会比使用WebForms时更多地考虑这些事情(无论好坏)隐藏这些概念抽象背后。