Was ist eine gute Methode zum verhindern, dass ein Benutzer von der Abgabe einer form zweimal?
Habe ich eine Kauf-Seite und ich will nicht dass der Benutzer in der Lage sein, um die Seite zu aktualisieren und erneut die form, wenn Sie auf den 'Bestellung abschließen' - Seite, weil es automatisch so festgelegt, dass Sie in unserem system über die Datenbank-Werte und Gebühren Ihrer Kreditkarte über paypal (nur wollen diese auf EINMAL)... ich habe gesehen, einige sites, die sagen " Don 'T drücken Sie aktualisieren, oder Sie bekommen doppelt belastet!', aber das ist ziemlich lahm offen lassen, um die Möglichkeit, was ist ein guter Weg, um nur erlauben, es einmal vorgelegt werden oder verhindern, dass Sie von der erfrischenden, etc?
PS: ich sah ein paar ähnliche Fragen: PHP: Stoppen Sie ein Formular versehentlich weiterverarbeitet werden, wenn Back gedrückt wird und Wie verhindere ich, dass die Zurück-und Aktualisieren-Schaltflächen Wiedervorlage meine form?, fand aber keine befriedigende Antwort... ein ASP.NET MVC-spezifische Antwort wäre auch ideal, wenn es einen Mechanismus für diese.
EDIT: Sobald Sie klicken Sie auf senden, sendet es an meinem controller, und der controller hat einige Magische und gibt dann eine Ansicht mit ein, um die vollständige Meldung, aber wenn ich auf aktualisieren auf meinem browser funktioniert die ganze " wollen Sie ihm diese form?', das ist schlecht...
- Sie bekommen mehr Antworten, wenn Sie markieren Sie als sprachunabhängig, da es nicht nur ASP.NET MVC, die betroffen ist, sondern alle Sprachen und frameworks, die Interaktion mit web-Formularen. (Natürlich, Sie könnten get code, wenn Sie verlassen ASP.NET MVC tag dort).
Du musst angemeldet sein, um einen Kommentar abzugeben.
Die standard-Lösung dafür ist, die POST/REDIRECT/GET Muster. Dieses Muster implementiert werden kann, mit so ziemlich jedem web-Entwicklungs-Plattform. Würden Sie in der Regel:
Ich 100% Stimmen mit RedFilter die generische Antwort, aber posten wollte einige relevante code für ASP.NET MVC speziell.
Können Sie die Post/Redirect/Get (PRG) Pattern zu lösen, die Doppel-postback-problem.
Hier ist eine grafische Darstellung des Problems:
Was passiert ist, wenn der Nutzer die Aktualisierung, versucht der browser erneut die Letzte Anfrage gemacht. Wenn die Letzte Anfrage war ein Beitrag, der browser wird versuchen, das zu tun.
Meisten Browser wissen, dass dies ist in der Regel nicht, was der Nutzer tun will, so werden Sie automatisch gefragt:
Aber das PRG-pattern hilft zu vermeiden, das insgesamt durch das senden der client eine redirect-Nachricht, so dass, wenn die Seite endlich angezeigt wird, ist die Letzte Anfrage des Browsers ausgeführt wurde, eine GET-Anforderung für die Ressource.
Hier ein große Artikel auf PRG, dass eine Umsetzung der MVC-Muster für. Es ist wichtig zu beachten, dass Sie nur wollen, zu greifen, um ein redirect, wenn ein nicht-idempotent Aktion auf dem server ausgeführt. In anderen Worten, wenn Sie eine gültige Modell-und tatsächlich blieb die Daten in irgendeiner Weise, dann ist es wichtig, sicherzustellen, dass die Anfrage nicht versehentlich doppelt eingereicht. Aber wenn das Modell ungültig ist, wird die aktuelle Seite und das Modell, die zurückgegeben werden sollen, so kann der Benutzer alle erforderlichen änderungen.
Hier ist ein Beispiel-Controller:
Während Sie mit der AUFTRAGSBESTÄTIGUNG Seite können Sie ein token, das Sie auch speichern in der DB/Cache. In der ersten Instanz der Bestätigung der Bestellung, Fragen Sie für diese token-Existenz und deaktivieren Sie das token. Wenn implementiert, thread-Sicherheit, werden Sie nicht in der Lage sein, zu senden die Bestellung zweimal.
Dies ist nur einer der vielen Ansätze möglich.
Geben Sie jedem Besucher eine einzigartige ID, wenn die Seite zuerst geladen wird. Hinweis: die ID, wenn das Formular abgeschickt wird. Sobald ein Formular abgesendet wurde mit dieser ID ist nicht zulässig, weitere Anfragen verwenden. Wenn Sie auf regenerieren klicken, werden die gleichen ID gesendet.
Hinweis, dass das PRG-pattern nicht vollständig zu schützen gegen mehrere Formular-Einsendungen, wie mehrere post requests abgefeuert bevor auch nur eine einzige Umleitung stattgefunden hat - dies kann dazu führen, dass Ihre Formular-Eingaben, die nicht als idempotent.
Tun, beachten Sie die Antwort zur Verfügung gestellt worden hier, die bietet einen workaround für dieses Problem, die ich zitiere hier für die Bequemlichkeit:
Einfach eine Weiterleitung von der Seite, die nicht alle die böse Sachen auf der "Danke für Ihre Bestellung" - Seite. Wenn dies erledigt ist, kann der Benutzer auf aktualisieren, so oft er mag.
Wenn Sie mag es nicht, leiten Sie den Benutzer auf andere Seite, dann durch die Verwendung meiner Weise Sie die Dosis nicht brauchen Post/Redirect/Get (PRG) Pattern und die user bleiben auf der aktuellen Seite, ohne Angst vor den negativen Auswirkungen der erneuten Einreichung des Formulars!
Verwende ich eine
TempData
Element und einHidden field
(eine Eigenschaft, die in derViewModel
von der form) zu halten, einen gleichenGuid
auf beiden Seiten (Server/Client
) und es ist mein Zeichen, um zu erkennen, wenn das Formular erneut Einreichen, indem Sie aktualisieren oder nicht.Letzte Gesicht des codes sieht wie sehr kurz und einfach:
Aktion:
Im Blick:
In View Modell:
Was denkst du?
Mache ich es einfach mit dem schreiben von 2 Klasse:
NoResubmitAbstract
abstrakte KlasseControllerExtentions
statische Klasse (Eine Erweiterung der Klasse fürSystem.Web.Mvc.ControllerBase
)ControllerExtentions:
NoResubmitAbstract:
Legte Sie in Ihre MVC-Projekt und führen Sie es... 😉
Aus der Spitze von meinem Kopf, erzeugen eine
System.Guid
in einem ausgeblendeten Feld auf die GET-Anforderung, von der Seite und verbinden Sie diese mit Ihrer Kasse/Zahlung. Prüfen Sie einfach und zeigt die Meldung "Zahlung bereits verarbeitet." oder so.Kazi Manzur Ahmed Rashid schrieb über diese (zusammen mit anderen asp.net mvc-best-practices). Er schlägt vor, zwei Filter zu behandeln, die die Datenübertragung zwischen der POST und den nachfolgenden KRIEGEN mit TempData.