Thus wrote Scott,
Hi,
I've been searching and testing and have not yet found the answer I'm
looking for.
I have an ASP.NET (vb) application with an ecommerce function. When
the user submits the page, I DON'T want them to be able to click on
the 'BACK' button and get back to the form - they may inadvertently
re-submit the page and get charged again. I WANT them to get the
"Page has expired" message.
Generally speaking, that's impossible. The HTTP 1.1 spec clearly says:
"History mechanisms and caches are different. In particular history mechanisms
SHOULD NOT try to show a semantically transparent view of the current state
of a resource. Rather, a history mechanism is meant to show exactly what
the user saw at the time when the resource was retrieved.
By default, an expiration time does not apply to history mechanisms. If the
entity is still in storage, a history mechanism SHOULD display it even if
the entity has expired, unless the user has specifically configured the agent
to refresh expired history documents."
Many browser do handle the concepts "history list" and "local cache" as one
entity, others don't. Some even change their behavior depending on specific
Cache-Control headers or the use of HTTPS.
I used to be able to do something like this with the META "Expires"
tag in classic ASP, but that doesn't seem to work with .NET.
If whatever you've tried to achieve with a META tag worked for you in ASP,
it will work in ASP.NET as well. This is a client specific behavior.
I've tried...
Page.Response.Cache.SetCacheability(HttpCacheabili ty.NoCache)
Response.Expires = 0
Response.Cache.SetNoStore()
Response.AppendHeader("Pragma", "no-cache")
To prevent caching, the first line usually suffices.
But in an internet scenario where you have no control over your users' browsers,
this approach is bound to fail. If you want to prevent duplicate form submits,
either
a) use redirect-after-post -- after processing the form submit, use HttpResponse.Redirect()
to send the user to the next page. The browser will only record the redirect's
GET in its history, not the POST. The drawback of this approach is another
roundtrip to the client for each form submit.
b) use a synchronizer token. Each web form includes a token (e.g. a GUID
or random number) that can be used only for one form submission. If you receive
a post back with an unexpected token, you can handle the duplicate submission
as you see fit. Here's a sample implementation:
http://tinyurl.com/lnx9w.
The drawback of this approach is that some browser will warn the user of
duplicate form submission, which many wrongly think of as an error message.
Thus, the user experience isn't really great: The user clicks back, thr browser
displays a warning, the user submits again away, and finally the application
displays a warning or an error after detecting the duplicate submisson --
that's not really nice.
Cheers,
--
Joerg Jooss
ne********@joergjooss.de