Verhindern Doppel-Einreichen / Veröffentlichen auf ASP.NET MVC Seite
Ich hoffe auf einige Rückmeldungen über die Methode, die ich verwenden möchten, für die Verhinderung von doppelten Datensätzen in einer ASP.NET MVC 4-Anwendung und der Domino-Effekte habe ich nicht, obwohl für die Benutzer Erfahrung.
Dem web-Formular hat sechs Eingabefelder und eine Schaltfläche "speichern" (ebenso wie eine Abbrechen-Schaltfläche), können die Benutzer bis zu 10 Minuten dauern Füllung in die form geben.
Nachdem die Felder eingereicht werden per post wird die Seite umgeleitet auf Erfolg /Misserfolg auf eine andere Seite, nachdem die Daten werden in einer Datenbank-Tabelle mit einer neuen Guid als Primärschlüssel.
Stoppen der Benutzer den speichern button drücken, viele Male, aber so dass der browser umbuchen Antrag auf eine geschlossene Verbindung, die ich anbieten will die Guid für neue Datensätze, Primärschlüssel als hidden-input-Feld, wenn das Formular wiedergegeben wird.
Wenn das umbuchen passiert, oder drückt der Benutzer speichern Sie mehrere Zeiten, die Datenbank-server weisen Sie den zweiten post des Datensatzes, weil ein doppelter Schlüssel, die ich überprüfen kann und fertig mit der server-Seite.
Aber diese neue, größere Probleme für mich?
- Was ist das problem?
- Das einzige mal, es gibt ein problem mit dem setzen der Primärschlüssel-Id in ein hidden-field ist, dass der Nutzer direkt in dieses Feld und ändern Sie den Primärschlüssel und aktualisieren jeden Datensatz in der Datenbank. nun, da Sie die Guid 's werden es fast unmöglich zu erraten Guid' s, die bereits ben verwendet und gehen in ein update über die bisherigen Benutzer der Formulare , wenn Sie eine ganze Zahl, dann würde ich, so es ist eine schlechte Idee
- Haben Sie Bootstrap? Weil es automatisch disabvles den button einmal geklickt hat und wenn nicht, die jquery oder einige loader-oder ausblenden der button einmal geklickt, bis u erhalten Antwort für den post-request'
- Derzeit, ohne diese neuen Sätze wurden wiederholt, bis zu sieben mal, wenn Kunden die Netze ausgelastet sind und die Benutzer erwarten eine schnellere Reaktion.
- Ich begann, deaktivieren Sie die Schaltfläche speichern, aber von Zeit zu Zeit es der Benutzer Sie ohne Weg. Die form war stuck, der server hatte keine post, und Sie müssen erneut alles. Das problem ist, dass der browser weiß nie, wenn der server nicht die POST oder, dass der browser nicht die Antwort.
- Möglich, Duplikat der Wie kann ich verhindern, dass mehrere Formular-Vorlage .NET MVC, ohne Javascript zu verwenden?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wenn Sie eine versteckte anti-forgery token im Formular (wie Sie sollten), können Sie Zwischenspeichern, die anti-forgery token auf die erste Einreichen, und entfernen Sie das token aus dem cache, wenn erforderlich, oder verfallen die zwischengespeicherten Eintrag nach der eingestellten Zeit.
Werden Sie dann in der Lage sein zu überprüfen, mit jeder Anfrage an den cache, ob die spezifische form eingereicht worden ist, und verwerfen es, wenn es hat.
Brauchen Sie nicht, um das generieren einer eigenen GUID, da diese bereits getan, wenn die Generierung der anti-forgery token.
UPDATE
Beim entwerfen Ihrer Lösung, bitte beachten Sie, dass jede Anfrage bearbeitet wird asynchron in einem eigenen thread oder vielleicht sogar auf völlig verschiedenen Servern /app-Instanzen.
Als solche, ist es durchaus möglich, dass mehrere Anfragen (threads) verarbeitet werden können, noch bevor der erste cache-Eintrag ist gemacht. Um dies zu umgehen, implementieren Sie den cache wie eine Schlange. Auf jedem submit(post-request), schreiben Sie den Namen der Maschine /id und thread-id, um den cache, zusammen mit der anti-forgery token... delay für ein paar Millisekunden, und dann prüfen, ob der älteste Eintrag im cache/Warteschlange für diesen anti-forgery token entspricht.
Darüber hinaus alle Laufenden Instanzen müssen in der Lage sein, um Zugriff auf den cache (shared cache).
Können Sie verhindern, dass der Doppel-klicken Sie auf von der client-Seite die Verwendung einiger jQuery, wenn Sie möchten.
In Ihrem HTML-Code haben Ihre senden-Schaltfläche etwas wie dieses:
In JavaScript (jQuery):
Dieser versteckt den button, bevor Sie es abschicken, so dass der Benutzer kann nicht zweimal klicken. Dies zeigt auch die Fortschritte, und auf Fehler, die Ihnen erlaubt, zu übermitteln. Möchten Sie vielleicht denken über das hinzufügen von ein timeout zu meinem obigen code.
Andere alternative ist die Verwendung von jquery zu packen form
$('#form-id').submit()
, aber Sie würden nicht in der Lage sein, die Fortschritte so leicht wie die ajax-calls, die ich getan habe.EDIT:
Ich würde noch empfehlen, auf der Suche nach Möglichkeiten, um zu verhindern, dass doppelte Einreichung von einem server-side stand-Punkt, nur zur Sicherheit.
JsonResult
: Sie können Aktionen erstellen, die im MVC-Anwendung, die berücksichtigt werden, um diese Arten von jQuery - / ajax-Aufrufe.Können Sie einfach umgehen, in der client-Seite.
Erstellen Sie ein overlay-div eine css-Klasse mit display none und eine große z-index und ein jquery-Skript, das zeigt, dass der div, wenn der Benutzer drückt den Absenden-button.
So wie ich das verstehe, die Sie planen zu halten, die den Primärschlüssel in ein hidden-input, wenn Sie das Rendern der Seite zunächst. Dies ist offensichtlich nicht eine gute Idee. So starten Sie mit, wenn Sie die Guid für die Implementierung in c#, es ist string und string als primary key ist nicht eine gute Idee (Finden Sie die Antwort für diese Frage ALSO).
Können Sie dieses Problem auf zwei Arten. Deaktivieren Sie zunächst die Taste auf den ersten Klick. Zweitens, bauen Validierungen in der code-behind-ohne sich auf den Primärschlüssel.
Manchmal, befassen sich mit es nur auf der client-Seite ist nicht genug. Versuchen Sie gen einen hash-code des Formulars und speichern Sie im cache (legen Sie ein Ablaufdatum oder so ähnlich).
der Algorithmus ist so etwas wie:
1 - User aus post
2 - Generieren der hash-post
3 - Überprüfen Sie die hash-cache -
4 - Post bereits auf cache? Ausnahme auslösen
5 - Post ist nicht auf den cache? Speichern Sie die neue hash-cache und speichern Sie die post auf Datenbank
Ein Beispiel:
Die cache-Funktion könnte etwa so lauten: