Preventing Duplicate Record Insertion on Page Refresh
page 5 of 6
by Terri Morton
Feedback
Average Rating: 
Views (Total / Last 10 Days): 174930/ 178

Solutions That Work By Trapping at the Database Level

[Download Code]

Should the user somehow manage to circumvent the two solutions described above, the last line of defense is at the database.  There are two methods that can be employed to prevent a duplicate record from being inserted into the database.  For each method, I've moved the SQL code into a stored procedure, since there are now more processing steps involved and these are easier to illustrate in a separate stored procedure.  Note however that a stored procedure is not strictly required in order for these methods to work.

The first method is to check whether the record exists in the database table before inserting it.  If the record does exist then the user will receive an error message.  The stored procedure in Listing 4 first does a lookup in the Employees table to see if the supplied FirstName and LastName combination already exists in the table.  If it does then a -1 result will be returned to the calling code.  If it does not, then an INSERT is attempted and the @@ERROR value is returned to the calling code.  The code in Listing 5 checks the stored procedure's RETURN value and displays a corresponding message to the user.

Listing 4 – Stored Procedure spAddEmployee_UsingExists

CREATE PROCEDURE spAddEmployee_UsingExists
(
      @FirstName varchar(50),
      @LastName varchar(50)
)
AS
DECLARE @Result int
BEGIN TRANSACTION
IF EXISTS
(
      SELECT
            NULL
      FROM
            Employees WITH (UPDLOCK)
      WHERE
            FirstName = @FirstName AND
            LastName = @LastName
) 
      BEGIN
            SELECT @Result = -1
      END
ELSE
      BEGIN
            INSERT INTO
                  Employees
            (
                  FirstName,
                  LastName
            )
            VALUES
            (
                  @FirstName,
                  @LastName
            )
            SELECT @Result = @@ERROR
      END
IF @Result <> 0
      BEGIN
            ROLLBACK
      END
ELSE
      BEGIN
            COMMIT
      END
RETURN @Result

Listing 5 – Server-Side Code Using Exists

Sub Button1_Click(sender As Object, e As EventArgs)
    Dim addResult As Integer = 0
    addResult = AddEmployee(firstName.Text, lastName.Text)
    Select addResult
        Case Is = 0
            Message.Text = "Success"
        Case Is = -1
            Message.Text = "Failure - record already exists"
        Case Else
            Message.Text = "Failure"
    End Select
    firstName.Text = ""
    lastName.Text = ""
End Sub

Function AddEmployee(firstName As String, lastName As String) As Integer
    Dim connectionString As String
    connectionString = "server='(local)'; trusted_connection=true; database='Northwind'"
    Dim dbConnection As New SqlConnection(connectionString)
    Dim dbCommand As New SqlCommand
    dbCommand.CommandText = "spAddEmployee_UsingExists"
    dbCommand.CommandType = CommandType.StoredProcedure
    dbCommand.Connection = dbConnection
    dbCommand.Parameters.Add(New SqlParameter("@FirstName",SqlDbType.NVarchar,10))
    dbCommand.Parameters("@FirstName").Value = firstName
    dbCommand.Parameters.Add(New SqlParameter("@LastName",SqlDbType.NVarchar,20))
    dbCommand.Parameters("@LastName").Value = lastName
    dbCommand.Parameters.Add(New SqlParameter("@Result",SqlDbType.Int))
    dbCommand.Parameters("@Result").Direction = ParameterDirection.ReturnValue
    Dim commandResult As Integer = 1
    Try
        dbConnection.Open    
        dbCommand.ExecuteNonQuery
        commandResult = CType(dbCommand.Parameters("@Result").Value,Integer)
    Catch ex AS SqlException        
        commandResult = ex.Number
    Finally
        dbConnection.Close
    End Try
    Return commandResult
End Function

The second method is to make use of the database table's ability to enforce a unique constraint.  To add a unique constraint on the Last Name and First Name columns of the Employee table, run this SQL command in Query Analyzer:

    CREATE UNIQUE INDEX [LastFirstUnique] ON Employees ([LastName], [FirstName])

With this method, there is no preliminary check to see if the record already exists; just let the database return an error when it tries to insert a duplicate record and check for this exception.  This method of course requires that the database allows for unique constraints.  With SQL Server, when the constraint is violated, error code 2601 is raised and returned to the calling code.  Note that the stored procedure has been stripped of its initial EXISTS check.  The disadvantage of this approach is that relying on exceptions for programming logic is considered to be a bad practice. 

To remove the unique constraint on the Employee table created above, run this SQL command in Query Analyzer:

    DROP INDEX [dbo].[Employees].[LastNameFirstNameUnique]

Listing 6 – Stored Procedure spAddEmployee_UsingSQLException

CREATE PROCEDURE spAddEmployee_UsingSQLException
(
      @FirstName varchar(50),
      @LastName varchar(50)
)
AS
      INSERT INTO
            Employees
      (
            FirstName,
            LastName
      )
      VALUES
      (
            @FirstName,
            @LastName
      )

Listing 7 – Server-Side Code Using SQLException

Sub Button1_Click(sender As Object, e As EventArgs)
    Dim addResult As Integer = 0
    addResult = AddEmployee(firstName.Text, lastName.Text)
    Select addResult
        Case Is = 0
            Message.Text = "Success"
        Case Is = 2601
            Message.Text = "Failure - record already exists"
        Case Else
            Message.Text = "Failure: " & addResult.ToString()
    End Select
    firstName.Text = ""
    lastName.Text = ""
End Sub
    
Function AddEmployee(firstName As String, lastName As String) As Integer
    Dim connectionString As String 
    connectionString = "server='(local)'; trusted_connection=true; database='Northwind'"
    Dim dbConnection As New SqlConnection(connectionString)
    Dim dbCommand As New SqlCommand
    dbCommand.CommandText = "spAddEmployee_UsingSQLException"
    dbCommand.CommandType = CommandType.StoredProcedure
    dbCommand.Connection = dbConnection
    dbCommand.Parameters.Add(New SqlParameter("@FirstName",SqlDbType.NVarchar,10))
    dbCommand.Parameters("@FirstName").Value = firstName
    dbCommand.Parameters.Add(New SqlParameter("@LastName",SqlDbType.NVarchar,20))
    dbCommand.Parameters("@LastName").Value = lastName
    Dim commandResult As Integer = 1
    Try
        dbConnection.Open
        dbCommand.ExecuteNonQuery
        commandResult = 0
    Catch ex AS SqlException
        commandResult = ex.Number
    Finally
        dbConnection.Close
    End Try
    Return commandResult
End Function


View Entire Article

User Comments

Title: 321312   
Name: 321312
Date: 2012-12-08 9:21:24 AM
Comment:
&lt;script&gt; alert("testing"); &lt;/script&gt;
Title: ss   
Name: sunil
Date: 2012-12-08 2:04:13 AM
Comment:
Test
Title: And I dont stand Again!!?   
Name: Christian Garcia
Date: 2012-11-28 5:02:26 PM
Comment:
And this resolution F5 trouble inserction submit!!?
Title: asa   
Name: sasa
Date: 2012-11-25 8:28:59 AM
Comment:
sasasa
Title: x   
Name: x
Date: 2012-11-16 11:26:19 AM
Comment:
x
Title: 1   
Name: 1
Date: 2012-11-13 3:04:32 AM
Comment:
1
Title: ABC   
Name: ABC
Date: 2012-11-11 11:30:34 PM
Comment:
ABC
Title: dtddfgggggggggggggggggggggggggggggggggggggg   
Name: fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
Date: 2012-10-11 3:49:24 AM
Comment:
fdgggggggggggggggggggggggggggggggggggggggggggggggggggggggggggfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffgggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg
Title: ftt   
Name: treter
Date: 2012-10-11 3:48:36 AM
Comment:
ertretretertttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt
Title: aaaaaaaa   
Name: bbbbbbbbbbb
Date: 2012-10-02 5:31:25 AM
Comment:
dddddddd
Title: eefee   
Name: eef
Date: 2012-09-27 4:59:49 PM
Comment:
efefefefef
Title: fddfd   
Name: fddfdd
Date: 2012-09-27 4:58:33 PM
Comment:
fddffdffdfdfd
Title: dfgdfg   
Name: dfgdfgdf
Date: 2012-09-24 1:00:36 AM
Comment:
sdfgsdfgsdfgsdgsdfgsdfg
Title: ererg   
Name: egdf
Date: 2012-09-24 1:00:08 AM
Comment:
dfgdfg
Title: asd   
Name: asd
Date: 2012-09-21 11:11:36 AM
Comment:
asdasd
Title: asd   
Name: asd
Date: 2012-09-12 6:08:56 AM
Comment:
asdasd
Title: test refresh   
Name: test name
Date: 2012-09-04 5:51:19 PM
Comment:
test comment
Title: dsfsdfsdfsdfdsfds   
Name: sdfds
Date: 2012-09-04 12:59:46 PM
Comment:
sfsdfsdf
Title: f   
Name: f
Date: 2012-09-04 3:00:23 AM
Comment:
gfg
Title: test   
Name: test
Date: 2012-08-26 9:15:01 AM
Comment:
test
Title: cx   
Name: xc
Date: 2012-08-23 6:54:58 PM
Comment:
xzzxc
Title: sample   
Name: erick
Date: 2012-08-23 3:31:35 AM
Comment:
vasvdhsavdasdhsafdfs
Title: Test   
Name: vinay
Date: 2012-08-17 10:05:24 AM
Comment:
hfsd o jlsjfl jlj ljlj klsjfldjsfs
dklsfjkldsjfkldsjfkljdslfj
Title: bla bla bla bla   
Name: fffffff .!.
Date: 2012-08-17 6:58:11 AM
Comment:
tasaci, dikus medikus771
Title: bla bla bla bla   
Name: fffffff .!.
Date: 2012-08-17 6:58:04 AM
Comment:
tasaci, dikus medikus77
Title: bla bla bla bla   
Name: fffffff .!.
Date: 2012-08-17 6:57:30 AM
Comment:
tasaci, dikus medikus
Title: www.namajkatipickata.com   
Name: dsa
Date: 2012-08-17 6:56:30 AM
Comment:
pojma nemate zimi se
Title: DDD   
Name: FFF
Date: 2012-08-17 6:55:57 AM
Comment:
dsadsada
Title: gggg   
Name: gggg
Date: 2012-08-15 5:25:37 AM
Comment:
gggggggggggggggggggggggggggggggggggggggg
Title: gggg   
Name: gggg
Date: 2012-08-15 5:25:19 AM
Comment:
ggggggggggg
Title: wsf   
Name: asdfas
Date: 2012-08-08 10:23:47 AM
Comment:
asdfasd
Title: jghj   
Name: hjh
Date: 2012-08-03 10:37:27 AM
Comment:
jghjghj
Title: 56   
Name: 546
Date: 2012-07-31 7:35:04 AM
Comment:
546
Title: Thank you   
Name: someone
Date: 2012-07-27 12:15:32 AM
Comment:
Thank you for your article.
Title: test   
Name: test
Date: 2012-07-27 12:09:36 AM
Comment:
test
Title: w   
Name: w
Date: 2012-06-29 7:54:36 AM
Comment:
w
Title: still hav problem   
Name: amit jamwal
Date: 2012-05-31 6:19:39 AM
Comment:
i want that when user click refresh button or hit F5 than the page loads for the first time i.e. all data is lost and page is reloads as it loads for the first time

thnx
amit
Title: test   
Name: test
Date: 2012-05-29 10:50:07 AM
Comment:
test comment
Title: f   
Name: sfd
Date: 2012-05-29 2:28:17 AM
Comment:
sd
Title: Nice Article   
Name: Umesh
Date: 2012-05-26 12:47:34 AM
Comment:
Thats work well. Simple & effective.
Title: Nice Article   
Name: Umesh
Date: 2012-05-26 12:07:37 AM
Comment:
Really Nice Article.
We do all the tricks mentioned here and dont get solution.
Thanks....
Title: rte   
Name: ertre
Date: 2012-05-22 12:54:42 AM
Comment:
ertr
Title: fgfgg   
Name: fgfg
Date: 2012-05-21 5:11:46 PM
Comment:
gffffffffffffff
Title: re   
Name: ter
Date: 2012-05-09 8:59:10 AM
Comment:
dsd
Title: trhgh   
Name: hhgfh
Date: 2012-05-08 12:03:31 AM
Comment:
fghgfhgfh
Title: willl   
Name: ql
Date: 2012-05-01 9:46:50 AM
Comment:
kl;m
Title: ssw   
Name: ss
Date: 2012-04-27 4:05:00 PM
Comment:
ss
Title: ss   
Name: ss
Date: 2012-04-27 4:03:52 PM
Comment:
ss
Title: sdfsdf   
Name: sdfsdf
Date: 2012-04-27 11:06:29 AM
Comment:
sdfsdfsdf
Title: question regarding viewstate during prerender event   
Name: Lekha
Date: 2012-02-24 3:19:06 PM
Comment:
Does it holds the original viewstate value during pre-render even at time of postback?

I didn't got the point we are assigning the session value to viewstate , but during postback, page load event will be fired, new session is set which we store again in viewstate, so how its going to be equal ?
Title: Would SqlDataSource Resolve Problem?   
Name: ASP.NET 3.5 Coder
Date: 2012-02-02 10:07:54 AM
Comment:
I've inherited some old classic ASP code that I'm upgrading to ASP .NET 3.5. The ASP code includes HTML textboxes that users would enter data into and a Submit button that would build a SQL Insert Into statement in a string variable, create a SQL Server database connection, and insert the record into the SQL Server table. I tried using this same approach in ASP .NET 3.5 because I would like to keep the same look for the users in the upgraded version, but I found it is vulnerable to duplicate Inserts as this article covers when the user clicks the Back button on the browser. Having used SqlDataSource with GridViews and FormViews in ASP .NET 3.5, I decided to try SQLDataSource with the HTML textboxes and Submit button. Now when the user fills in the textboxes and clicks the Submit button, I use code similar to the following:
SqlDataSource1.InsertCommand = "Insert Into ..."
SqlDataSource1.Insert()
This seems to insert the record once and not reinsert the record if the user uses the Back button. My question is does the SqlDataSource take care of preventing duplicate record insertion on page refresh automatically? It doesn't seem to be a problem when I use SqlDataSource with a GridView or FormView control either. So, I suspect that SqlDataSource might automatically take care of this.
Title: selectindexchanged of dropdownlist   
Name: Tawhid
Date: 2012-01-02 10:20:57 PM
Comment:
i avoid page refreshment by this code-
Session("update") = Server.URLEncode(System.DateTime.Now.ToString())
but now when i select a data from dropdownlist the page is not refrsh.
Title: Excellent   
Name: .Net Programmer
Date: 2012-01-02 7:07:38 AM
Comment:
You are really genius.
Title: Excellent   
Name: Stéphanie Garniche
Date: 2011-10-07 5:04:55 AM
Comment:
Good examples didn't work (i like it for understand) and severals soluions does work THANK U VERY MUCH
Title: Simple but great one!!   
Name: ShahRizal
Date: 2011-09-09 4:44:18 AM
Comment:
Thanks dude. This issue sound simple but when it's involve sequence,then you know it's mess your data.
Title: Avoid Users from clicking the back button or refersh   
Name: Faisal
Date: 2011-08-24 10:31:09 AM
Comment:
One good line of defense could be simple ones. try to build a website where users don't have to press the back button very often. Of course there is no guarantee that they won't but it would help.

For example, in a email scenario, opening attachments in a new tab would avoid the users to press back button if the attachment is opened in the same page.
Title: doesnt work in this case   
Name: Java dev
Date: 2011-05-26 4:21:00 AM
Comment:
What if i want to duplicate the data after some period of time. I mean Transaction time will be different, rest of data needs to duplicate. But this should not be the case for refresh or f5
Title: not thanks   
Name: swami
Date: 2011-03-18 11:26:30 AM
Comment:
but i want code in C#
Title: Thanks   
Name: Ramesh
Date: 2011-03-16 8:23:41 AM
Comment:
It is very usefull for us.
Title: Thanks alot Terri   
Name: Rajesh
Date: 2011-03-08 5:31:02 AM
Comment:
Your post is very good.But the problem is using Sharepoint i am sending at a time to database and Customlist.If i prevent sending to database successful also data is going to Custom list.So pls tell me any other option to my mail anuraj44@gmail.com

Thanks in advance
Title: Thanks a lot Terri :-)   
Name: saurabh
Date: 2011-02-08 1:31:04 PM
Comment:
fantabulous , exceptional event handling, i m ur big fan now :-)
Title: Thanks to Terri, Thanks to Dirk.   
Name: BSRK
Date: 2011-01-29 5:44:17 AM
Comment:
Thanks Terri for the helpful article. after reading & checking various options, i felt detecting browser's refresh is a simple option for my purpose. I specially thank Dirk for providing 'IsRefreshed' function without using 'OnPreRender'.
Title: Excellent answer   
Name: gajendra
Date: 2011-01-25 5:37:51 AM
Comment:
This is a good notes for .net , i have tried to use all type of option given . all are working well thanks for help.
Title: Impressive Article   
Name: Danish Mehmood Gakhar
Date: 2010-12-08 12:35:24 PM
Comment:
It is very helpful artifact, I am very thankful to its author. May Allah bless him / her.
Title: Any workaround for submit button with postback URL   
Name: Srini
Date: 2010-12-02 4:39:47 AM
Comment:
I am facing same problem in form submission.
My Scenario-
I have an aspx page on which form fields (input boxes) and submit button generates dynamically.
Each input box has asp.net validations applied
Input button has post back URL assigned, due to URL redirection rules used.
I have applied this solution but View state variable is always found empty for button click event. Please let me know any work around for this issue.
Title: .net Person   
Name: .net Person
Date: 2010-11-24 5:50:00 AM
Comment:
I think this ver good article and most wonderfuk part of this article is the approach of the author.

Well done.... Keep it up.
Title: Excellent Explanation   
Name: Mohammad Yusuf Ansari
Date: 2010-11-24 12:59:06 AM
Comment:
Its indeed an execellent approach to solve this problem.
I appreciate the efforts of 'Terry' to come out this article.
Title: Asp.net   
Name: Keyur
Date: 2010-11-19 12:05:37 AM
Comment:
The purpose of this article is to discover how to prevent the data from being reinserted into the database when the browser's Refresh button is pressed.
Title: Dev   
Name: Mark
Date: 2010-11-07 8:50:11 PM
Comment:
Instead of detecting second postback use secondary cookie and default values on the controls? You check cookie creation time and if it is within 5minutes then it is refresh.... Just and idea, didn't try myself.
Title: nice work   
Name: rahul jain
Date: 2010-10-20 6:19:42 AM
Comment:
that's working nice
thank u so much for posting this artical
Title: help me   
Name: Nitya
Date: 2010-10-15 5:53:27 AM
Comment:
on refreshing the insert in happening i have already used all the codes given here but not satisfied i need to disable F5 and Refresh
Title: can any one change this to c#   
Name: Abli
Date: 2010-10-07 7:07:58 AM
Comment:
Sub Button1_Click(sender As Object, e As EventArgs)
If AddEmployee(firstName.Text, lastName.Text) = 0
Message.Text = "Success"
Response.Redirect(Request.Url.ToString(), false) ' will include the querystring
Else
Message.Text = "Failure"
End If
firstName.Text = ""
lastName.Text = ""
End Sub
Title: Preventing Duplicate Record Insertion on Page Refresh   
Name: hamid sattarzadeh
Date: 2010-09-09 4:54:32 AM
Comment:
thank you very very very very very very much.
i can solve my problem with help of your article
Title: Session("update") = Server.URLEncode(System.DateTime.Now.ToString())   
Name: Santhosh
Date: 2010-09-04 2:23:58 AM
Comment:
Thank you very much.This is a useful technique to control unwanted value insertion into a database when the page is refreshed. My special thanks to this article owner.
Title: Preventing Duplicate Record Insertion on Page Refresh   
Name: hamid sattarzadeh
Date: 2010-08-24 7:05:21 PM
Comment:
thank you very very very very very very much.
i can solve my problem with help of your article.
Title: very Nice   
Name: Uj
Date: 2010-07-05 10:58:21 PM
Comment:
Thx. For Help..:-)
Title: mr   
Name: ahmed
Date: 2010-06-28 8:52:48 AM
Comment:
very good
Title: Avoiding Duplicate record insertion on page refresh in ASP.NET   
Name: Shalini Kondapalli
Date: 2010-04-20 10:20:16 AM
Comment:
precisely what I had been looking for...Thanks
Title: Avoiding Duplicate record insertion on page refresh in ASP.NET   
Name: Eliza Sahoo
Date: 2010-03-10 12:31:20 AM
Comment:
Thanks,
The post was quite helpful.One of most common issue which many of the web developers face in their web applications, is that the duplicate records are inserted to the Database on page refresh. If the web page contains some text box and a button to submit the textbox data to the database. In that case when the user insert some data to the textbox and click on the submit button, it will save the record to the Database and then if the user refresh the web page immediately then the same record is again saved to the database as there is no unique keys that can be used to verify the existence of the data, so as to prevent the multiple insertion.
Title: Avoiding Duplicate record insertion on page refresh in ASP.NET   
Name: Eliza Sahoo
Date: 2010-02-15 7:18:35 AM
Comment:
Thanks,
The post was quite helpful.One of most common issue which many of the web developers face in their web applications, is that the duplicate records are inserted to the Database on page refresh. If the web page contains some text box and a button to submit the textbox data to the database. In that case when the user insert some data to the textbox and click on the submit button, it will save the record to the Database and then if the user refresh the web page immediately then the same record is again saved to the database as there is no unique keys that can be used to verify the existence of the data, so as to prevent the multiple insertion.
Title: Thanks   
Name: Sachin
Date: 2010-01-09 9:57:58 AM
Comment:
I wish I had found this 4 hours before...
Title: 2cents   
Name: Jean-Francois Lanouette
Date: 2010-01-08 10:08:13 AM
Comment:
I personnaly ended up by using timesptam stored in an hidden field and in the session upon page rendering... upon submit i valid that they are the same, if yes i let the request go and reset the timestamp in the session to -1...

Also, to be more user friendly, with the back button users , i do an ajax call in the page to display a warning when the page as already submitted and process...

Finally u can also add a check for empty/bad referrer at the same time
Title: no title   
Name: peter G
Date: 2009-12-27 9:13:13 PM
Comment:
Nice article.
Nice tests which supported conclusions.
Title: Well written   
Name: Allen
Date: 2009-11-19 11:35:54 AM
Comment:
Very well written and concise... your approach to providing what solutions did or did not work provide a better understanding of which option makes the most sense for developers.
Title: Great Morton   
Name: Abeloni
Date: 2009-11-10 7:44:39 AM
Comment:
Well done- I have searched a while for anything like this and God bless You that you came up with that! Great thanks.
Title: Good Soln.   
Name: krishpuneet
Date: 2009-11-02 12:50:29 AM
Comment:
Thnk's
Title: Cool Sol   
Name: Yu
Date: 2009-08-30 5:13:48 PM
Comment:
Good solution, Thanks
Title: Tnx   
Name: Gantumur
Date: 2009-08-17 12:23:03 PM
Comment:
nice nice Tnx
Title: Nice Article   
Name: Jeya Kumar. M
Date: 2009-08-17 5:23:54 AM
Comment:
nice concept to prevent duplicate records
Title: Very Usefull Article!!!   
Name: Saranya.R
Date: 2009-07-28 3:47:49 AM
Comment:
Great Article. Thanks a Lot!
Title: very good   
Name: Nitesh Gautam
Date: 2009-07-22 7:51:50 AM
Comment:
Very good article, but there could have been a simple way to do this.. change the name of button after inserting the record like btn.text = "updated" and in the function first check the name of the button. ex:
if btn.text <> "update" then
exit sub
else
insertfunction()
endif

but for beginer a good article...
Nitsy
Title: Simple with Ajax   
Name: Bhanu Mukund
Date: 2009-07-20 1:52:39 PM
Comment:
this issue can be resolved by using Ajax. Don't submit the entire form. Place the elements in updatePanel.
Title: Greate Article   
Name: MOHAMMAD SHAFIULLAH
Date: 2009-06-22 9:24:16 AM
Comment:
GREATE ARTICLE.I WAS SEARCHING GOOGLE AND LUCKLY I FOUND THIS WHICH DESCRIBES BEST PEREVENTIVE SOLUSION.THANKS A LOT
Title: NO MORE PROBLEMS   
Name: Basheer
Date: 2009-06-22 5:47:57 AM
Comment:
Very informative article. As a beginner what I have done is..created 2 identical pages. In page load event of both pages response redirected to the other page..NO MORE PROBLEMS
Title: Thank you   
Name: Brian
Date: 2009-06-12 7:29:07 PM
Comment:
Very informative!
Title: Best Way   
Name: Ali Baba
Date: 2009-06-04 12:03:31 PM
Comment:
Don't submit forms at all. Ajax them
Title: Duplicate Entry in Database on page refresh   
Name: Vipin Gupta
Date: 2009-06-04 5:53:28 AM
Comment:
This is a great concept of preventing to insert duplicate value in database............
Here Server.transfer is not working
But Response.redirect is succefully do his work.
Thanks
Title: Refresh Problem   
Name: Hardee[
Date: 2009-06-03 5:27:06 AM
Comment:
response.redirect not work bcoz on successful insertion Javascript function call which not work
Title: Mind blowing   
Name: Amresh chandra
Date: 2009-05-21 8:55:09 AM
Comment:
Mind blowing answer.and from this answer i clear my concept that how a page posted to server

Thanks
Title: hamzh   
Name: hamzh
Date: 2009-03-23 10:54:52 AM
Comment:
This is a very good article, Also my problem is solved by this article.
thanx
Title: Mr   
Name: Kervin Ramen
Date: 2009-03-19 5:30:00 AM
Comment:
THANKS!!! Good article!
Title: Prventing from Duplicated Records   
Name: Sri
Date: 2009-03-13 5:35:31 PM
Comment:
what if the application is a simple mail sending and not having any database insert transactions. how do we go at that time
Title: Thanks u very muc   
Name: chandu
Date: 2009-02-18 10:09:06 AM
Comment:
By dis i solved my problem.
Title: Prventing from Duplicated Records   
Name: Biswa Bhusan Dash
Date: 2009-02-17 5:11:25 AM
Comment:
This is a very good article, Also my problem is solved by this article.

Thanx
Title: Prventing from Duplicated Records   
Name: Hekmatullah
Date: 2009-02-01 7:00:22 AM
Comment:
Dear all,
I have learnt many things from your Website, if possible please continue your work and give me permission to Add special Artical with Examples.
Thanks
Hekmatullah Khyber
From Afghanistan
Title: Good one   
Name: Swetha
Date: 2009-01-13 5:40:59 PM
Comment:
Very informative.Liked the performance comparision of different approaches.

Thank you.
Title: Excellent   
Name: Velmurugan
Date: 2009-01-09 8:39:41 AM
Comment:
For last one month i just wondering to get the solution for this problem... Really excellent article. I visited more than 50 sites for this problem... thank u very much
Title: Refresh problem   
Name: Rahul Dhadphale
Date: 2009-01-08 1:31:58 AM
Comment:
Nice artical it is very usefull, i was facing excectly same problem and resolved the problem by using your one of the option
Thanks
Title: Nice Work!   
Name: Giwa
Date: 2008-12-20 7:34:11 AM
Comment:
Beautiful work; pls keep it up. May u live long to continue to spawn more of this beautiful solution. Thankz.
Title: what if   
Name: Abhishek Shrivastava
Date: 2008-12-14 11:27:19 PM
Comment:
Hi
Yes Your Solution is OK.But if I increment a primary key
data field then this Problem Persist because due to increment (As my Prject Requires)it insert into database
while refreshing(F5).abhi_foryou04@yahoo.com.PLs
send a solution if i can restrict this at Front end.
abhishek shrivastava ,India
Title: Thanks   
Name: Farzad Badili
Date: 2008-10-27 4:21:52 AM
Comment:
You gave me a better picture by presenting the "Ideas that did not work" section. :)

Thanks for your time.
Title: Very good   
Name: indravijay jadeja
Date: 2008-10-24 9:20:13 AM
Comment:
hi team,

i love this page....
it has solved my problem

thank you
regards,
indravijay jadeja
indravijay@shwettechnolabs.com
09322945245
Title: Broken Link   
Name: Rvalencia
Date: 2008-10-23 8:54:17 AM
Comment:
great info,
try to keep the links updated : Build Your ASP.NET Pages on a Richer Bedrock.
Title: prevent re click event on page refresh   
Name: vaibhav-9911686759
Date: 2008-09-11 10:43:49 AM
Comment:
if ur using any control which is going to be bind data after that click evnt thn plzzzz

please load data under (not post back).....

if (!IsPostBack)
{

LoadGridComments();
}

protected void lnkbtnMApprove_Click(object sender, EventArgs e)
{
LinkButton TempLnkBtn = (LinkButton)sender;
HiddenField TempHf = (HiddenField)TempLnkBtn.Parent.Parent.FindControl("hfMComntID");

PRC_CommentsController modctrl = new PRC_CommentsController();
PRC_ModCommentsInfo modinfo = new PRC_ModCommentsInfo();
modinfo= modctrl.ModCommentGet(Convert.ToInt32(TempHf.Value));
modinfo.Approved = 1;
modinfo.ActionTaken = 1;
modctrl.ModCommentUpdate(modinfo);
LoadGridComments();

}
Title: Thanks   
Name: Justin
Date: 2008-07-17 10:49:51 AM
Comment:
Thanks much, your article really helped me tons.
Title: Thanks   
Name: Gautam
Date: 2008-07-15 3:33:37 AM
Comment:
Nice Article, I was in serious problem, and this article helped me a lot.
For me Browser Refresh Solution helped my puspose
Title: I need some shortcut method that work   
Name: richa
Date: 2008-07-07 7:36:06 AM
Comment:
I need some shortcut method that work
Title: The best solution for duplicate row insert   
Name: Palash
Date: 2008-06-18 6:09:54 AM
Comment:
#region PreRender
protected override void OnPreRender(EventArgs e)
{
Session["REFRESH_CHECK_GUID"] = System.Guid.NewGuid().ToString();
ViewState["REFRESH_CHECK_GUID"] = (string)Session["REFRESH_CHECK_GUID"];
}
#endregion
#endregion

#region IsRefreshed
public bool IsRefreshed
{
get
{
if (Session["REFRESH_CHECK_GUID"] == null
|| ViewState["REFRESH_CHECK_GUID"] == null
|| Session["REFRESH_CHECK_GUID"].ToString().Equals(ViewState["REFRESH_CHECK_GUID"].ToString()))
{
return false;
}
else
return true;
}
}
#endregion
Title: It doesn't work !   
Name: Wyatt Wong
Date: 2008-04-29 7:06:44 AM
Comment:
I found the code doesn't work at all. When the page is not postback, the Session("update") variable has stored the current date/time, when the page is going to load, the PreRender event is fired and the ViewState("update") is assigned to the Session value. When the button1_click event is fired for the first time, the data can be inserted to the database, and then the PreRender is fired again, which assign the SAME Session value to the ViewState. Now when user press F5 or click on the Refresh icon, the Session part is skipped but the value in Session and ViewState is STILL the SAME, so the button1_click event handler will be fired AGAIN and execute the insert record !!!
Title: Ajax helped me out   
Name: Eric
Date: 2008-04-10 9:49:37 AM
Comment:
Great article and great discussion. I would like to add my experience in hopes it may help somebody else. My app has a form for entering logs, like a journal. Checking the db for dupes was not really viable, since a duplicate could valid. The only difference would be timestamp. And that is enterred by the db itself, so it is always different. By putting my gridview in an Ajax updatepanel, an async call does not cause the browser to keep any post data, and a refresh doesn't resend the async data. Thanks again.
Title: great help   
Name: manish
Date: 2008-04-03 2:39:51 AM
Comment:
really gr8 approach
Title: Thanks a lot..   
Name: Nikhil
Date: 2008-04-03 1:02:23 AM
Comment:
You gave me a better picture by presenting the "Ideas that did not work" section... :)

This saved my time. Should have saved many others time too. Great work.

Thanks for your time.
Title: My solution   
Name: Gene
Date: 2008-03-23 8:59:24 AM
Comment:
I had this recurring problem on various platforms, so my favorite solution is platform independent. On the form I define the [input type=hidden name=trapRefresh value='refresh'] tag and on submit I change its value to 'post'. Then before processing the request I analyze this value, and if it's 'refresh' I just skip the database part.

Why I like it:

1. It works for any other platform such as PHP, not just ASP.
2. It doesn't require a database roundtrip.
3. The overhead of carrying one extra input field there and back is negligible.
4. It's expandable, in that you can use it to determine how exactly your submit happened.
5. It actually ALLOWS double entry. In some situations it's an absolute valid case.

Hope this will help somebody.
Title: -   
Name: -
Date: 2008-01-25 2:26:57 AM
Comment:
would it work by just disabling view state those controls?
Title: Can there be another way?   
Name: Calexmy
Date: 2008-01-25 2:21:15 AM
Comment:
This solution is ok and its a helped. Can there be any other solution, to prevent duplication when page is refresh,without using the server.transfer()?

thank
Title: Thanks a million   
Name: Soren Of Persian
Date: 2008-01-20 7:23:04 AM
Comment:
that is an old problem in my company :D
Title: Excellent Solution   
Name: Eric Stockdale
Date: 2008-01-17 12:54:36 PM
Comment:
Using the Response.Redirect approach worked very well for me in my specific situation where losing previous view state information was acceptable (actually desirable)
Title: This is small question but very imp,Can Any body help to me?   
Name: krishnamraju
Date: 2007-12-12 12:00:36 AM
Comment:
I took 2 textboxes & 1 button, When i click the button that the textbox data will be stored in database. ok but after refresh the button again same data will be stored in database?
why After refresh the browser again will be stored the data in database?
Title: Great   
Name: Rathinavel
Date: 2007-11-19 2:02:43 AM
Comment:
This is nice ....i want to disable the refesh and F5 key ......
Title: Great   
Name: Bozena
Date: 2007-10-10 10:44:21 AM
Comment:
Great article!!!! Very nicely written and helpful. Thank you :)
Title: Mr   
Name: Hannan Azam
Date: 2007-09-12 5:09:14 PM
Comment:
GREAT article...
very nicely explained all the scenarios
Title: Thanks   
Name: Farhan Abu-Leil
Date: 2007-09-07 4:18:52 PM
Comment:
I love this solution... thank you for posting it :)
Title: Excellent   
Name: victor (asp.net newbie)
Date: 2007-08-21 7:16:44 AM
Comment:
I bow down to thee, (and others who contributed).
Title: Thanks   
Name: Matt
Date: 2007-07-27 4:47:45 AM
Comment:
Thank you everyone. I was happy to find this article, just over two years after it was written!

-George
-Date: 12/7/2006 4:15:56 PM

Your solution rocked it for me.

Thanks again G. and everyone.
Title: Webmaster   
Name: Vadim
Date: 2007-07-19 3:57:01 PM
Comment:
To Terri:
Great job! Thank you very much!!!!!!

To Raj Yadav:
Yes, it would be nice to skip the last even during refresh at all. It would be great if you could offer some solution.

To Dirk:
Great solution! I like it the most than any other offered here especially since it's suitable for other similar problems that do not involve any data bases. I am using it right now.

To Isaac:
Yes, Session/ViewState method offered by Terri did not work for me either. After some troubleshooting I found out that ViewState["update"] and Session["update"] have 1-2 seconds difference. It seems that OnPreRender and onLoad events are fiered with more than 1 second appart on my page. That's the resaon I use Dirk's solution.
Title: Good Resource   
Name: Zubair Masoodi
Date: 2007-06-19 2:22:27 AM
Comment:
The arricle seems to provide a Good solution to a technological Limitation
Title: Great Information   
Name: Chintan Jani
Date: 2007-06-16 4:42:57 AM
Comment:
Truely useful Thank you very much!!!
Title: very useful   
Name: Jilju
Date: 2007-06-06 12:39:33 AM
Comment:
it is very useful for me. thank you
Title: very helpful artical   
Name: motaz salah
Date: 2007-05-12 3:43:10 PM
Comment:
this artical become very helpful for me.
Title: halp ful   
Name: Sudhanshu Tiwari
Date: 2007-05-01 4:59:57 AM
Comment:
this artical become very helpful for me.
thanks
Title: Bravo!   
Name: Andreas Symeonides
Date: 2007-04-27 10:09:11 PM
Comment:
Excellent article on a hot subject expressed in a humble tone! I like the fact that not only you described solutions that work but also solutions that do not work so that people can get a better picture.

I also amused myself with this: "It actually worked so well that once one record was successfully inserted into the database, no more could be added"

I think I'll go with a database flavor.

Thanks a lot Terri....
Title: HelpFul   
Name: Mayur
Date: 2007-04-11 5:23:20 AM
Comment:
Very Help Full one !!
Thanks !
Title: Good aricale   
Name: shafik
Date: 2007-02-16 12:21:52 AM
Comment:
nice explanation
Title: Not Satisifed   
Name: B Praveen Kumar
Date: 2007-02-15 8:22:36 AM
Comment:
Your articles perfectly balances if we are doing insertions in the database but what if we are doing updations?

Suppose if we stop at the database level and if there is a updation process for the page we cannot stop at database level. Even we the user dont modiffed the existing data also we need to update the existing record with the values in the fields.
Title: Similar Viewstate/Session Approach   
Name: Dirk
Date: 2007-02-14 7:47:40 AM
Comment:
Great article!
With some slight changes I determine the refresh in Page_Load without the use of Page_PreRender:

private bool IsPageRefresh = false;

protected void Page_Load(object sender, EventArgs e)
{
if (Page.IsPostBack)
{
if (ViewState["postid"].ToString() != Session["postid"].ToString())
IsPageRefresh = true;
}
Session["postid"] = System.Guid.NewGuid().ToString();
ViewState["postid"] = Session["postid"];
}

Then you can check IsPageRefresh where needed.
Title: Use Database ID   
Name: Rick
Date: 2007-02-10 11:50:34 AM
Comment:
In most cases of inserts into the database there will be a primary key field in the table. Why not test for that instead of some combination like firstname, lastname?

When adding a new record from a Formview I use an INSERT stored procedure that returns the new primary key using SCOPE_IDENTITY(). The NewID goes into a Session("NEWID") value which calls a SELECT stored procedure WHERE ID = @NEWID. This populates the ItemViewTemplate and EditItemTemplate with the newly inserted record so the user can review or edit the newly inserted record.

If the user tries to insert the record again, couldn't you write code on Protected Sub FormView1_ItemInserting that would check to see if the Session("NewID") can call a Datareader WHERE ID = @NewID. If the recordset exists then the new insert is prevented. If not, it is allowed to go through?

Rick
Title: Thanks so much!   
Name: Rosita
Date: 2007-02-05 3:03:31 PM
Comment:
Thank you for this article, it was really helpfull

Rosita
Title: Nice   
Name: nju
Date: 2007-02-01 4:57:22 AM
Comment:
Thanks...its really nice...U have done great job..
Title: I beg to Differ   
Name: John Pequeno
Date: 2007-01-30 6:00:24 PM
Comment:
You have done a great job at comparing options! And your conclusion was well thought out, from a C programmer's perspective :), as it was entirely based on performance.

There are at leasts 2 perspectives you've entirely ignored in your conclusion.

1) Design perspective, where does it logically make sense to do such validation?
- This I am not sure of in the given case and I will leave for someone else to answer. However considering the nature of what you are trying to attain, I believe it is logical to block refresh data duplication at the UI level itself, instead of going all the way back to your data source and back up again.

2) Cost perspective, what are the cost differences in the different methods?
- Typically the Database Server is the most expensive server a web application must use. Compared with a web server which only has the cost of the hardware and OS (which would include the web server in the .NET case), the Database server must usually be a much beefier server to handle the large loads, and the Database licenses are sold on a per server basis and are generally a few thousand per server for an enterprise/commercial grade database. In my case, a web server typically costs $3k, where a DB server may cost $10k.

Also, I hope you were running the DB server on the same machine as your web server for benchmarking purposes, otherwise this was not even a logical comparison. If you are using some other DB server for testing, you are then dedicating 2 machines as opposed to 1 to the task, and the DB server is likely a better machine.

Great article over all. I will be using the Session solution myself to manage this issue.

John Pequeno
Title: @Terri Morton I'm not satisfied   
Name: Raj Yadav
Date: 2006-12-20 5:17:24 AM
Comment:
Hi,

I'm not satisfied with your solution. I don't want button click action perform on page refresh event of broswer. I want to skip the last event of my page when page refresh. Hope you will look into this matter again and will provide better solution......
Title: Simple SQL-based solution   
Name: George
Date: 2006-12-07 4:15:56 PM
Comment:
To prevent duplicate inserts simply check the values of the fields that would indicate a duplicate entry. This is a simpler variation of the author's "stored procedure using exists" solution. Say my table should have only one record with Year, Period and CategoryID as the combined unique data, then my insert query or stored procedure would look like this:

if not exists (
select valueid from [CategoryData] where CategoryId = @CategoryId and Year = @Year and Period = @Period)
BEGIN
INSERT INTO CategoryData (CategoryId, Year, Period, ActualValue, TargetValue) VALUES (@CategoryId, @Year, @Period, @ActualValue, @TargetValue)
END

This accomplishes the same thing as setting table constraints in the database, but does not create an error condition if the record already exists. The user can refresh as many times as they please, but if the record already exists, no duplicate record will be inserted. This may not work for all scenarios, but is an easy way to immunize your insert queries against duplicate records. This technique can be used in the insert command code of asp.net datasources. Hope this helps somebody out there.
Title: Simple solution   
Name: RB
Date: 2006-11-26 11:36:39 AM
Comment:
In the form set a session ("post") = true
before you do the DB-stuff you check the session state
if session("post") = true then do DB-stuff..
After succesfully having done your DB-stuff change the session to session ("post") = false

Works like a glimp!! :-)
Title: Great Work!   
Name: Robert
Date: 2006-11-23 6:58:12 AM
Comment:
I used the session and viewstate option and it really worked well to solve my problem and instead of response .redirect i used server.transfer and that gave my result thanks once again
Title: Well Explained   
Name: Faisal Fayyaz Kiyani
Date: 2006-10-27 10:37:02 AM
Comment:
Well explained , good.
Title: Very good   
Name: Daniel Spitale
Date: 2006-10-25 12:40:02 PM
Comment:
Thank you very much! It was just what I need.
Title: I have a question   
Name: Grace
Date: 2006-10-21 3:40:52 PM
Comment:
Hello, I'm a begginer of .NET applications and I'm searching for the code that can prevent inserting duplicate data and luckily I found your site and it seems very helpful. But unfortunately I was not able to add a data to the Northwind and I don't know why. I'm using a sql server management studio express edition(its the free edition).
Title: Server-Side Code Using Response.Redirect Success Indication?   
Name: Claude
Date: 2006-10-12 1:39:34 PM
Comment:
For the solution using Server-Side Code Using Response.Redirect, how does the user know that the post was successful? All they would see is a blank form.

Please advise. Thanks,

Claude
Title: Browser's Refresh: Error On page   
Name: Samer
Date: 2006-09-05 5:49:06 AM
Comment:
Session and Viewstate problem

Object reference not set to an instance of an object

Any Help.......
Title: session not working   
Name: Isaac
Date: 2006-07-26 2:33:37 PM
Comment:
I am using a self-referencing asp, and session doesn't work. Does anybody know why? Thanks in advance!

Isaac
Title: Congratulations   
Name: Sandeep Raj
Date: 2006-07-21 2:00:09 AM
Comment:
Thank you very much Terri Morton, It 's really work for my application.
Title: Thank You   
Name: Steve
Date: 2006-07-20 8:17:25 PM
Comment:
Thank you for taking the time to sort through such a tricky topic that nobody likes to really put time into ;-)
Title: At last something verrry good!!!!!   
Name: Surajit Paul
Date: 2006-07-11 4:00:39 AM
Comment:
I was looking for long but with no luck. Suddently I got this article that put me out of the dark. Thanks!!!!
Title: Good Article   
Name: Lakshmi
Date: 2006-06-01 2:52:32 AM
Comment:
Very useful article.Helped to solve similar problem in my project.Looking forward for more such good artilcles.

Lakshmi
Title: An Offer For You   
Name: Joe
Date: 2006-05-05 3:00:05 AM
Comment:
hey Terri Morton ,

You sounds good man.
i would like to hire u for my company
if interested contact me at jawsanto@gmail.com

regards
joe
Title: It worked   
Name: Abhishek nigam
Date: 2006-05-01 4:35:13 AM
Comment:
Thank u for providing such wonderful suggestions.
Title: Database level check is a must   
Name: Rameswar Datt K
Date: 2006-04-27 2:42:53 AM
Comment:
Database level check is a must even if you use any of the above methods,because user may not only refresh the page but may enter same data again by mistake and press Save.

Response.Redirect is very simple and useful to use, where database does not involve, for example sending mail when user forgets his password scenario. Here if user refreshes the page mail will be sent twice.

I too tried some of the above solutions that do not work and finally got Response.Redirect option myself.

When I am trying to dig whether some other good approach is available, I came here.

Thanks, good and useful article.
- Rameswar Datt K -
Title: Be careful!   
Name: Eugim Migue
Date: 2006-04-25 10:12:21 PM
Comment:
the database approach was fine...but it i hope it won't be taken "literally"..on the article's listing, the filtered fields where the employee's lastname and firstname; then if such a combination exists, raise an exception. But i think that it is very possible, and highly probable, that two entities (in this case, persons) will have the same name; and disallowing an insert on the basis of a lastname-firstname condition is not a very good idea..so i must say that the suggested approach is indeed efficient, but not at all "safe", meaning the example in the article is not to be taken "as is". perhaps, storing a sessionid (on the first execution of the insert command) per employee record would be fine (this of course would neccessitate a new field, e.g. "sessionidinsert"), then using such field instead as the ultimate tag (identifier) to know if the user really did only hit the refresh button...the database approach nonetheless, i still think, is the best solution. :D
Title: Database Approach   
Name: Eugim Migue
Date: 2006-04-25 9:53:05 PM
Comment:
yeah...nice article.. the article itself was very humble and fair in its approach with the known possible options available for developers when handling user refreshes...the suggested approach in solving such a problem, i highly agree of. nothing beats, for me, the use of SPs when building database driven applications: they make applications highly maintainable and scalable. thanks a lot for this article.
Title: Excellent and Professional   
Name: Muhammad Hafeez
Date: 2006-04-03 3:12:04 PM
Comment:
I benefitted greatly from this article. Since I am updating the database via an ascx page on an aspx page. I had tried some of the "Ideas That Did Not Work" myself with the same results as in the article for about 3 days. The one which finally worked was the one recommended by Terri. Way to go.
Title: re: Error on Page   
Name: Terri Morton
Date: 2006-03-09 11:12:11 AM
Comment:
Hi Elvarasu,

In the article you'll see that the sentence directly above that code snippet says:

"Note that ViewState needs to be enabled on the page for this to work; if ViewState is not enabled then a hidden form field may be used instead."

When I disable ViewState on my test page and run the code, I see the same exception you are seeing. The solution is to either enable ViewState or use a hidden form field instead.
Title: Error on Page   
Name: Elavarasu
Date: 2006-03-08 1:48:11 AM
Comment:
When executing the page which you given testDuplicatePrevention_UsingSessionAndViewState.aspx

i am receiving the following error,

Object reference not set to an instance of an object.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.

Source Error:


Line 30: End If
Line 31:
Line 32: If Session("update").ToString() = ViewState("update").ToString() Then
Line 33:
Line 34: If InsertData() = 0 Then

What is the solution for this.
Title: Good one   
Name: Renish
Date: 2006-02-12 12:01:07 PM
Comment:
I found the session/viewstate one better though it takes highest time to execute but easy to implement and things stay in the developer's contral.
Title: Response.Redirect doesn't work   
Name: Angry Debugger
Date: 2005-11-23 4:19:08 AM
Comment:
use the go back button and do submit again
Title: Ujjwal   
Name: Ujjwal Prakash
Date: 2005-11-18 12:17:25 PM
Comment:
Awesome,
It really helled a lot
10 on 10
REgards,
Ujjwal
Title: Dork Admin   
Name: UberDork
Date: 2005-10-31 11:13:34 AM
Comment:
I agree, the Response.Redirect is the way to go. That or you diable the F5 button.

mulalhlahalhalhaha!
Title: Best article so far   
Name: wtoh
Date: 2005-10-05 9:29:16 PM
Comment:
Best article i have read for the whole day, very inspiring! i will be using the response.redirect approach, and use my own session variable to store the view state if need be.

Thanks Terri!
Title: Putting a non-working solution to work   
Name: Jeremy Miller
Date: 2005-09-29 8:14:37 PM
Comment:
For your non-working methodology which uses sessions, you comment "since once that Session variable was set there was no way to know when it was okay to reset it to the initial value." Let me extend your method to one known to work. For a more complete explanation and example code, please see my site ( http://www.script-reference.com/repeat_form_submission.php ).

After the form data has been processed, change your session variable to match the form variable. Then, for the next submission the data will be valid, but trying to repeat the old submission gets rejected.
Title: Good Article, but sadly not helping me   
Name: Sunil J
Date: 2005-09-28 10:41:14 AM
Comment:
This is a really good article but unfortunately it has not helped my scenario.

In my case, after the button click i am displaying another panel. I am using Session and Viewstate scenario. When the new Panel is displayed, the PreRender event is called. Which results in equalling the values.

I guess it would have to be some other method for me.

Cheers

Sunil J
Title: Good article.. useful for newbie   
Name: Sandeep
Date: 2005-09-27 3:31:17 AM
Comment:
My problem is solved......
Thanks..
Title: Amazing Article   
Name: Mrunmayee
Date: 2005-09-15 3:05:20 AM
Comment:
It was amazing and have helped me alot...thanks Terri..

- Mrunmayee
Title: goood solution   
Name: Aditya
Date: 2005-09-02 6:08:24 AM
Comment:
Hi you did a good job i found it very helpfull
Title: ASPNETPRO   
Name: George
Date: 2005-08-24 3:11:23 PM
Comment:
Dino Esposito wrote a very good article on this in ASPNETPRO 2004
He wrote a component to handle that very thing.
Peace!
Title: Very good article...   
Name: Heiko
Date: 2005-08-20 4:52:41 PM
Comment:
I ran into the same problem and thanks to your article I found some good points for implementing a solution.
I prefer the database level approach. I also think about using the Session ID as a database field where I can do a lookup. If there is a record with this Session ID I will perfom an update, if there is none it is a new record. Maybe this could be another good point.
All in all I don't like the concept behind this PostBack mechanism at all but have to live with it.

Thanks again and keep up your very good work!
Heiko
Title: mal   
Name: rob
Date: 2005-08-18 10:19:40 AM
Comment:
Why not delete the details before you insert them. They can then only ever exist once!!!!! If they are not there too delete then hey, no problem!!!
Title: Ooops   
Name: Jack Kwong
Date: 2005-08-17 10:30:41 AM
Comment:
Oops, didn't fully read the introduction, but you can still use this inconjunction with the solution in the article.
Title: Simple Solution   
Name: Jack Kwong
Date: 2005-08-17 10:26:32 AM
Comment:
Why not just disable the button after post? Most users don't use the refresh button on the browser. This doesn't work on all browsers though.

Button1.Attributes.Add("onclick", "this.form['Button1'].disabled=true;")

OR

Button1.Attributes.Add("onclick", "this.disabled=true;")
Title: Good article   
Name: Karthik
Date: 2005-08-17 2:11:01 AM
Comment:
A very well explained article. Hope you keep exploring more and write more.
Title: Good Article   
Name: Fahad Nasim
Date: 2005-08-15 7:50:32 AM
Comment:
Its very nice article. Thanx for allocating time in writing it.
I have a different view than your suggestion.
In Database approach, the SQL Exception approach is better, because, if there will be a huge amount of data in that table (in which you are trying to insert). The 'UsingExists' approach will be taking more time than the SQLException approach. Because in SQL Exception approach, you have an index which will result in a faster insert method or faster error result.
This is my perspective, I don't know, if I have some lacking knowledge regarding the SQL insertion method.
Title: Very concrete   
Name: Patrick.O.Ige
Date: 2005-08-15 2:30:28 AM
Comment:
Very good article..
I think the best solutions showed the right avergae time to process..I enjoyed your article Terri.
Patrick
Title: Educating users   
Name: BrianOC
Date: 2005-08-12 10:07:49 AM
Comment:
One approach I think is worth considering IF your app allows users to delete items is to let them make the mistake. They can delete it and learn not to refresh very quickly. I like the idea of making your users more savvy with web based applications because it makes life easier in the long run. Having said all that excellent article.
Title: Bookmarked!   
Name: Joe Gakenheimer
Date: 2005-08-12 9:26:15 AM
Comment:
Yep, this article has been bookmarked.

I had used Response.Redirect method when I was learning .net, but when you are using someone else's code you don't always grasp what's going on. So thanks for the reminder.

I also like the database approaches to solving the duplicate record problem. Like I said, this article has been bookmarked because I don't need the database approach for my current application, but know in the future projects I will.
Title: Yet another alternative   
Name: Raymond
Date: 2005-08-11 8:56:57 PM
Comment:
This is another approach which i adopt. I would suggest that not every page should prevent pastback refresh, as the refresh might help in some sense. Have a read on this good piece.

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnvs05/html/BedrockAspNet.asp
Title: Good Ideas   
Name: Unknown
Date: 2005-08-11 6:35:25 PM
Comment:
There's some very good ideas here, however, the easiest approach is to generate a GUID, store it in the user's session, pass it to the client and then look for it again on post. Been using this method for years and works perfect everytime.

postId = left(server.CreateObject("scriptlet.typelib").guid,38)

if session("PostId") <> Request.Form("PostId") then
session("PostId") = Request.Form("PostId")
Title: agree with conclusion   
Name: imqwer
Date: 2005-08-11 10:40:27 AM
Comment:
very nice article, well done !!
I agree with the conclusion drawn. Using Exists is the best way to go about this problem.
Title: Excellent article   
Name: Bhaskar
Date: 2005-08-11 8:08:04 AM
Comment:
It's an excellent article, this will help developers to solve a most commonly occuring problem with great deal of ease & flexibility.
Title: Good approach   
Name: gregorybologna@gmail.com
Date: 2005-08-09 12:49:29 PM
Comment:
The database method discussed above will not work for database fields that contain xml data and similar fields where the column contains non-key values.
Title: Where the conclusion does NOT work   
Name: Dave Rollins
Date: 2005-07-29 10:29:32 AM
Comment:
Terri - thanks for taking the time to write this article.

Just one minor point... if you have something like an insert-only financial transaction table you are inserting into, and you are using a database controlled identity column to ensure uniqueness, then it is completely valid if the data the user submits is duplicated.

I'm adopting the sledgehammer approach myself. In my opinion this is a UI problem, not a DB problem.

Of course catching duplicate insert errors nicely in the DB or first checking to make sure a record exists before insert and handling the error that way is a must if you want your app to be completely, totally, absolutely, bulletproof.

-Dave
Title: Updated code for the EXISTS database trapping   
Name: Terri Morton
Date: 2005-07-27 4:00:13 PM
Comment:
I realized today that the code I had posted to check for the existence of a record before inserting it into the table had a flaw - there was no locking in between the check and the insert. So there was the potential of another user slipping in an identical row. I've now wrapped the code in Listing 4 in a transaction, and added a WITH (UPDLOCK) hint in the SELECT statement.

Many thanks to everyone with the positive and constructive feedback! It's great to hear of others experience and to learn more on this topic.
Title: Awesome! Can'r always use database approach.   
Name: Jim Chese...
Date: 2005-07-27 11:57:54 AM
Comment:
This one line (Response.Redirect(Request.Url.ToString(), False) did it for me! (It kills the http headers)
I had a trickier problem too.
You see, I ALLOW "duplicates" in my page logic!
I simply had to stop the fact that the page REFRESHing was the equivalent of a user cliking the button.
This did it for me!!
Jim C
Title: Software Engineer   
Name: Uppalapati Giri Prasad
Date: 2005-07-26 12:38:41 AM
Comment:
Hi Terri Morton
It is really good article.I appreciate the eforts u have put.Continue the same and help the developers.
Title: Good   
Name: Nandu
Date: 2005-07-20 12:59:39 AM
Comment:
Hi,
Today i learnt SQL Exception Approach, an other feather in my crown, Thank you.

i would have really appreciated if this article was posted well early during the release of dotnet, as there were quite a few programmers struggling to find a solution on this problem.
But, i would also like to bring to your kind notice as this was way back solved by self during classic ASP life. The approach was by using a session variable with hidden textbox. Instead of time, i used a value which increments ONLY when user pressed the button.
Nandu
Title: Alternative solution   
Name: Jeremy Schell
Date: 2005-07-18 5:18:53 PM
Comment:
I haven't had time to fully document the alternative suggestion we use but I have uploaded brief details, database setup and the server control we use here for others to take advantage of, http://www.tectonicconcepts.com/netproducts.aspx?id=84667942 Good Luck
Title: very good   
Name: Rajendran
Date: 2005-07-08 5:08:30 AM
Comment:
Fine Article....
Keep it Up
Title: Very good source of information   
Name: TPrice
Date: 2005-06-30 4:21:21 PM
Comment:
Thanks very much. Very nice information.

I was unable to use the response.redirect method due to using tab controls. The session/view state variables method (listing 3) did the trick.

I intend to bookmark this article for future applications.
Title: Good article, here's an alternate suggestion   
Name: Jeremy Schell
Date: 2005-06-30 8:42:00 AM
Comment:
Good article, we use a database approach on all forms which works exceptionally well.

We have a table that maintains unique submission keys

create table FormKeys (
siteID INT,
formID INT,
dateCreated datetime,
formKey varchar(50)
)

When each form is called we create a new entry within the FormKeys passing a GUID to the formKey field along with the appropriate siteID and formID which are unique for each client and form on their site. (This way we can manage all forms from one database) Next we place this value within a hidden field. We found that using cookies, session vars and viewstate have a risk of failure as you noted so hidden fields always work.

Upon postback we check to see if that key exists within the table for the correct siteID and formID. We optionally allow forms to expire so the post date is sometimes checked against the dateCreated within the table. If the key exists then the form is allowed to post. Once posted the key is deleted from the table and can not be used. If when the form is posted and the key does not exist, we know it is either a double submission or a "spam" submission by someone trying to force entries into the database. For each form, even if it is a multi-step form on an aspx page, each one will get a new formKey for it's next post.

We've wrapped this up into a standalone class as well as a web service for remote access and easy distribution among applications.
Title: feedback on the "Preventing Duplicat records"   
Name: Wally
Date: 2005-06-29 7:12:12 AM
Comment:
Really nice article. Personally, I would think that the database approach would be the fastest, but its VERY NICE that you examined the alternatives and measured their speed.
Title: It 's great   
Name: Justin Wang
Date: 2005-06-28 11:40:21 PM
Comment:
Thank you very much Terri Morton, It 's really work for my application.
Title: re: what's the diff?   
Name: Terri Morton
Date: 2005-06-24 2:52:19 PM
Comment:
Hi John, I used the sledgehammer approach. :-) Thank you for drawing my attention to that.

The Response.Cache.SetExpires(DateTime.Now.AddDays(-1)) sets the Expires value in the HTTP header to the current date/time less 1 day.

The Response.Cache.SetCacheability(HttpCacheability.NoCache) sets these 3 HTTP header values:
Cache-Control: no-cache
Pragma: no-cache
Expires: -1

This in effect overwrites the effects of the earlier SetExpires, which makes the SetExpires pointless in this scenario.

I used Response.Cache.SetValidUntilExpires(false) to make sure ASP.NET doesn't ignore the Cache-Control HTTP header. This is set to false by default when using Response.Cache, so it was not truly necessary to specify it explicitly.

So yes, in short, it looks like this one line would have been enough:
Response.Cache.SetCacheability(HttpCacheability.NoCache)

Page output caching is a whole topic unto itself. :-)
Title: Preventing Duplicate Record Insertion on Page Refresh   
Name: Roger Sutro
Date: 2005-06-24 11:33:07 AM
Comment:
Thanks for this well-structured and thorough article!!!
P.S. I'm opting to use a redirect (to deal to prevent duplicate form submissions by reloading page).
Title: Congratulations   
Name: Bilal Haidar [MVP]
Date: 2005-06-23 3:01:21 PM
Comment:
I would like to congratulate you Terri for this well-worked article.

Regards
Title: Very good article indeed   
Name: Mahesh Zabardast Zakhas
Date: 2005-06-23 10:18:56 AM
Comment:
Very good article , nice explanation. I would like to thank Terri Morton for sharing her knowledge with us.She is indeed doing a noble job. Thanks once again
Title: what's the diff??   
Name: John Hopper
Date: 2005-06-23 9:20:07 AM
Comment:
Shouldn't one of these be enough?:

Response.Cache.SetExpires(DateTime.Now.AddDays(-1))
Response.Cache.SetCacheability(HttpCacheability.NoCache)
Response.Cache.SetValidUntilExpires(false)
Title: Good Conclusion   
Name: Dave
Date: 2005-06-22 12:52:09 PM
Comment:
I would agree with the conclusion of the article. The best approach is to trap the problem at the database level. That should always be the first line of defense.

I also think the Response.Redirect should be used in conjunction with this and the hidden form field trick should be used as well.

This issue points out the whole problem with the asp.net postback model in general. Its just not really cool to have pages post to themselves, the user is still going to see that confusing refresh dialog or a page expired message.

I worked on a project that one of the parameters was that a user could never see that message, simply because in the old version it created a high volume of support calls.

Response.Redirect not perfect helps with the refresh issue.
The hidden form field, through script can allow you to refresh the page if they hit the back button.

Nice article.

- Dave






Community Advice: ASP | SQL | XML | Regular Expressions | Windows


©Copyright 1998-2024 ASPAlliance.com  |  Page Processed at 2024-10-07 8:23:29 AM  AspAlliance Recent Articles RSS Feed
About ASPAlliance | Newsgroups | Advertise | Authors | Email Lists | Feedback | Link To Us | Privacy | Search