Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent Form Resubmission in ASP.Net (without redirecting to myself)

I have a master page with a Form element (<form runat="server">), a content page with a Button element (<asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Sync" />), and a Code Behind page that contains the Button1_Click function.

The user comes to the page and clicks the button. The Code Behind code executes (on the server) in which it updates some tables in a database. The last thing the Code Behind code does is to set the InnerHTML of a Span element on the content page with a success or failure message.

That all works great. The problem is if the user refreshes the page, the Form is resubmitted and the browser asks if that's really what the user wants. If the user responds in the affirmative then the Code Behind code is re-executed and the database is updated again. If the user responds negatively, then nothing happens.

Re-executing the Code Behind code is not a big deal. It won't hurt anything. But it's not really the behavior I want.

I know I can do a redirect back to the page with Response.Redirect() but then the user never sees my success or failure message. I should mention that the message is really more than just "Success" or "Failure" otherwise I suppose I could add something to the QueryString on the Redirect.

Is there a way to reset the Form element from the Code Behind code so that if the user refreshes the page the Form is not resubmitted?

The master page...

<%@ 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>

The content...

<%@ Page Language="C#" AutoEventWireup="true" MasterPageFile="~/Site.master" CodeBehind="SyncToCloud.aspx.cs" Inherits="IntuitSync.SyncToCloud" %>
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
    <asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Sync" />
    <span runat="server" id="SyncStatus"></span>
</asp:Content>

The Code Behind...

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Globalization;
using System.Web;

namespace IntuitSync
{
    public partial class SyncToCloud : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            //
        }

        protected void Button1_Click(object sender, EventArgs e)
        {
            /*
                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.
        }
    }
}

Any and all help is greatly appreciated.

like image 449
user2008632 Avatar asked Feb 07 '13 21:02

user2008632


People also ask

How can stop form resubmission in asp net?

After Form submission, when the Refresh Button in the Browser is clicked or the F5 key is pressed, a warning popup comes up which warns against Form resubmission. The solution is very simple, either the page must be redirected to itself or to some other page in order to avoid this particular behavior.

How do I stop resubmission of a form?

You can prevent form resubmission via a session variable. Yes we can use microtime() as well as time() also instead of rand() , whatever function or variable that gives different value we can use it. BUT make sure that you set that value to SESSION variable.

How do you avoid confirmation resubmission?

Solution 1: Disable Confirm Form Resubmission From Chrome Right click on your chorme shortcut, select properties. In the target field, add: “-disable-prompt-on-repost” without the quotes after chrome.exe.

What technique is used to help with form resubmission errors?

Method #4 Use the PRG Pattern What can pass as a solution to rectifying the Confirm Form Resubmission error is switching the POST method to the entire PRG pattern. Whenever any page needs a form on it, design it in such a way that it does not post the data directly to the server.


2 Answers

The issue is you're doing a form POST which, if the user subsequently refreshes the page, does what it's supposed to do: resubmit the POST. There is no way around it. Therefore, the options available to you are as follows:

  1. Redirect to a confirmation page, passing the operation results to the confirmation page in some way (typically reload from some data repository if it's something that's not feasible for a query string/cookie/etc.).
  2. Redirect to the same page, but pass the success message via a query string parameter (or go silly and store it in the session/ViewState/what-have-you-silliness).
  3. Instead of posting, do a form get since it seems you aren't posting any values, only initiating some sort of server-side processing. To do so simply change your form from a post to a get, or just do a link. The danger here is you shouldn't be doing any transformative/destructive operations in any get operation.

NOTE: make sure you sanitize any and all user input (treat user input as evil always).

You probably would be happiest with the last option, but it all depends on what "do a bunch of stuff and put the results in syncResults..." really entails.

UPDATE (years later)

While it should be obvious it might not be obvious enough to some users: you should NEVER open yourself up to XSS attacks by directly displaying un-sanitized "success message via a query string parameter". The suggestions assumed this was obvious, but in retrospect it should have been explicitly clear in that regard.

like image 97
Ted Avatar answered Oct 23 '22 16:10

Ted


i would suggest going into JASON route

on 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.
    }

on 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
                                }
                            } 
                        }); 
            }

Markup on buutton

<asp:Button ID="Button1" runat="server" OnClientClick="SyncStatus(); return false;" Text="Sync" />
like image 23
Kamran Ul Haq Avatar answered Oct 23 '22 16:10

Kamran Ul Haq