views:

156

answers:

8

Is there an easier way to prevent a duplicate insert after refresh? The way I do it now is to select everything with the all fields except ID as parameters; if a record exists i don't insert. Is there a way to possible detect refresh?

+4  A: 

Assuming it's a database, you could put a unique constraint on the combination of "all fields except ID" and catch the exception on an insert or update.

Austin Salonen
i like this alot. First thing i will try tomorrow morning.
Eric
colleagues here are too scared to try this one. They don't like tampering with the DB.
Eric
You could also put a *Key* on your DataSet that does this as well.
Austin Salonen
A: 

What DB are you using? If it's MySQL, and certain other factors of your implementation align, you could always use INSERT IGNORE INTO .... EDIT: Struck for SQL Server

Alternatively, you could create "handler" pages, e.g. your process looks like this:

  1. User attempts to perform "action"
  2. User is sent to "doAction.xxx"
  3. "doAction.xxx" completes, and redirects to "actionDone.xxx"
  4. ???
  5. Profit!

EDIT: After re-reading your question, I'm going to lean more towards the second solution; by creating an intermediate page with a redirect (usually an HTTP/1.1 303 See Other) you can usually prevent this kind of confusion. Checking uniques on the database is always a good idea, but for the simple case of not wanting a refresh to repeat the last action, this is an elegant and well-established solution.

Dereleased
i'm using sql server
Eric
+3  A: 

I agree with @Austin Salonen that you should start by protecting the DB with primary keys, unique constraints and foreign keys.

That done, many websites will include some JS behind submit buttons to disable the button immediately before sending on the request. This way, users who double click don't send two requests.

Michael La Voie
the JS trick is great for reducing the load on your server, but it isn't going to protect you. What about users who have JS turned off, or even maliciously submit multiple requests?
rmeador
@rmeador - Agreed. There is no real solution without the DB protection. The JS technique can only be thought of as a convenience for users.
Michael La Voie
A: 

I second the option to redirect a user to another (confirmation) page after the request has been submitted (a record inserted into the database). That way they will not be able to do a refresh.

You could also have a flag that indicates whether the insert request has been submitted and store it either on the page (with javascript) or in the session. You could also go further and store it somewhere else but that's an architectural decision on the part of your web application.

If you're using an AJAX request to insert a record then it's a bit harder to prevent this on the client side.

I'd rather do an indicator/flag then compare the fields. This, of course, depends on your records. For example, if it is a simple shop and the user wants to make an identical order then you will treat it as a duplicate order and effectively prevent the functionality.

Alen Siljak
+1  A: 

I think you may want to the EXISTS function. Here's a simple explanation of EXISTS I found through google.

ChadNC
I love this way. However what if I'm comparing null values? Because I would be saying = null and nothing can be = null but it can be isNull.
Eric
you could try adding some like "IS NOT NULL" into your query on the fields that could possibly be null. Hard to be certain without seeing an example of the query.
ChadNC
+1  A: 

Like Dereleased said, use a 303-based redirect. Make the form submission use POST and then after saving have it send a 303 header and send them to the post-submit URL via a Location header which will be fetched via GET and a refresh will not be re-posting data.

SleighBoy
+1  A: 

It has been a long time since I have done any real web work. But back in the 1.1 days I remember using ids associated with a postback to determine if a refresh had occured.

After a quick search I think this is the article I based my solution from:

http://msdn.microsoft.com/en-us/library/ms379557%28VS.80%29.aspx

It basically shows you how to build a new page class that you can inherit from. The base class will expose a method that you call when you are doing something that shouldn't be repeated on a refresh, and an IsPageRefresh method to track if a refresh has occured.

That article was the basis for alot of variations with similar goals, so it should be a good place to start. Unfortunately I can't remember enough about how it went to really give any more help.

Glenn Condron
A: 

There are several ways to accomplish this.

Try the techniques mentioned in this article.

Ramesh S