D'éviter la Double Soumettre / Post sur ASP.NET MVC page
Je suis l'espoir de quelques commentaires sur la méthode que j'ai l'intention d'utiliser pour la prévention des enregistrements en double dans un ASP.NET MVC 4 application et les répercussions je n'ai pas bien pour l'expérience des utilisateurs.
Le formulaire web a six champs de saisie et un bouton "enregistrer" (ainsi que d'un bouton annuler), les Utilisateurs peuvent prendre jusqu'à 10 minutes en remplissant le formulaire.
Une fois que les champs sont soumis par l'intermédiaire d'un post de la page est redirigée sur la réussite ou l'échec d'une autre page, une fois que les données sont enregistrées dans une table de base de données à l'aide d'un nouveau Guid en tant que clé primaire.
Pour arrêter les utilisateurs en appuyant sur le bouton enregistrer de nombreuses fois, mais permet au navigateur de rediffuser la demande sur une connexion fermée j'ai l'intention de fournir le Guid pour les nouveaux records de la clé primaire comme un champ caché lorsque le formulaire est généré.
Si le reposter qui se passe, ou que l'utilisateur appuie sur enregistrer plusieurs fois, le serveur de base de données de rejeter le second poste de l'enregistrement en raison d'un double de la clé, qui je puisse vérifier et à faire face aux côté serveur.
Mais cela ne crée plus de problèmes pour moi?
- Quel est le problème?
- Le seul moment où il y a un problème avec mettre l'Id de Clé Primaire dans un champ caché est que les utilisateurs peuvent aller dans ce domaine et modifier la clé primaire et la mise à jour de chaque enregistrement dans la databse. maintenant, étant donné qu'ils sont Guid, il serait presque impossible de deviner un Guid qui ont déjà ben utilisés et placés dans une mise à jour au cours du premier utilisateur des formulaires , si vous avez été en utilisant un entier, alors je voudrais donc c'est une mauvaise idée
- Avez-vous utilisé Bootstrap? Parce que c'automatiquement disabvles le bouton une fois cliqué et si ne pas utiliser jquery ou certaines chargeur ou masquer le bouton une fois cliqué jusqu'à recevoir u de réponse pour la requête post'
- Actuellement, sans cela, de nouveaux records ont été répétées jusqu'à sept fois, lorsque les clients des réseaux sont occupés et que les usagers attendent une réponse plus rapide.
- J'ai commencé la désactivation du bouton enregistrer, mais de temps en temps, il a laissé à l'utilisateur, sans aucun moyen d'avancer. Le formulaire a été bloqué, le serveur n'a pas obtenu le poste, et ils ont à retaper tout. Le problème est que le navigateur ne sait jamais si le serveur n'a pas obtenu le POSTE ou que le navigateur n'ai pas la réponse.
- Double Possible de Comment puis-je éviter de multiples formulaire de soumission .NET MVC, sans l'aide de Javascript?
Vous devez vous connecter pour publier un commentaire.
Si vous utilisez un caché anti-faux jeton dans votre formulaire (comme vous), vous pouvez mettre en cache les anti-faux jeton sur la première soumettre et retirez le jeton à partir du cache si nécessaire, ou de se périmer l'entrée du cache après un certain laps de temps.
Vous serez alors en mesure de vérifier à chaque requête contre le cache si le formulaire a été soumis et de le rejeter si elle l'a fait.
Vous n'avez pas besoin de générer votre propre GUID comme cela a déjà été fait lors de la génération de la lutte anti-contrefaçon jeton.
Mise à JOUR
Lors de la conception de votre solution, veuillez garder à l'esprit que chaque demande sera traitée de manière asynchrone dans son propre thread, ou peut-être même entièrement différents serveurs /app instances.
En tant que tel, il est tout à fait possible que plusieurs demandes (threads) peut être traitée, même avant la première entrée de cache est faite. Pour contourner ce problème, de mettre en œuvre la cache comme une file d'attente. Sur chaque submit(requête post), écrire le nom de la machine /de l'id et l'id de thread pour le cache, ainsi que l'anti-faux jeton... retard de quelques millisecondes, puis vérifiez si l'entrée la plus ancienne dans le cache/file d'attente pour que la lutte contre le faux jeton correspond.
En outre, toutes les instances en cours d'exécution doit être capable d'accéder à la mémoire cache (cache partagé).
Vous pouvez éviter le "double clic" du côté client à l'aide de certains jQuery, si vous le souhaitez.
Dans votre code HTML, votre bouton soumettre être quelque chose comme ceci:
En JavaScript (jQuery):
Cela permet de masquer le bouton avant même qu'elle essaie de l'envoyer, afin que l'utilisateur ne peux pas cliquer deux fois. Cela témoigne également de progrès, et en cas d'échec, leur permet de soumettre à nouveau. Vous pouvez pensez à ajouter un délai d'attente de mon code ci-dessus.
Une autre alternative est d'utiliser jquery pour saisir la forme
$('#form-id').submit()
, mais vous ne pouvez pas être en mesure de suivre les progrès aisément comme l'appel ajax que j'ai fait.EDIT:
Je voudrais encore vous recommandons de chercher des moyens d'éviter la double présentation à partir d'un serveur-side point, juste pour des raisons de sécurité.
JsonResult
: vous pouvez créer des actions dans votre application MVC qui sont pris en charge pour ces sortes de jQuery / ajax appels.Vous pouvez simplement composer avec elle dans le côté client.
Créer une superposition div, une classe css avec display none et un grand z-index et un script jquery qui montre que la div lorsque l'utilisateur appuie sur le bouton soumettre.
Que je comprends, vous envisagez de garder la clé primaire dans un caché d'entrée lorsque vous êtes rendu de la page initialement. Évidemment, ce n'est pas une bonne idée. Pour commencer avec, si vous êtes en utilisant le Guid de la mise en œuvre en c#, il est de la chaîne et d'avoir de la chaîne en tant que clé primaire n'est pas une bonne idée (Voir la réponse à cette question DONC).
Vous pouvez résoudre ce problème de deux façons. Tout d'abord, Désactivez le bouton sur le premier clic. Deuxièmement, créer des validations dans le code derrière, sans compter sur la clé primaire.
Parfois, traiter avec elle uniquement côté client n'est pas assez. Essayez de gen un code de hachage de la forme et de l'enregistrer dans la mémoire cache (définir une date d'expiration ou quelque chose comme ça).
l'algorithme est quelque chose comme:
1 - de l'Utilisateur à la suite de l'
2 - Générer le hachage de la poste
3 - Vérifier le hash en cache
4 - Post déjà sur le cache? Jeter l'exception
5 - Post n'est pas dans le cache? Enregistrer la nouvelle valeur de hachage sur le cache et enregistrer post sur la base de données
Un exemple:
Le fonctionnement de la mémoire cache peut être quelque chose comme ça: