2009-11-10 3 views
1

J'ai un formulaire. Sur soumettre d'un bouton, il insère un enregistrement dans le db. Si je retourne dans mon navigateur et actualise la page, elle la renvoie à nouveau, provoquant toutes sortes de problèmes, comme vous pouvez l'imaginer. Comment est-ce que je m'assure que l'utilisateur ne peut pas actualiser la page précédente et l'état de cette page fait une autre soumission automatique sur l'actualisation comme ceci?Empêcher la nouvelle soumission de données dans l'actualisation du navigateur

  1. Je n'utilise pas ViewState. Je l'ai en fait désactivé dans la directive de page
  2. Non, Response.Redirect ne résout PAS ce problème. L'utilisateur peut toujours revenir en arrière avec le bouton arrière et rafraîchir au point du navigateur où ils ont présenté et il continuera à fonctionner envoyer en aval les données de l'événement du bouton à mon DL insérer
+0

Si la deuxième communication effectivement * illégale *, ou est-il simplement * habituellement * non intentionnel? –

+0

Beaucoup de gens cherchent des réponses à cette question. Moi aussi inclus dans cette liste. Le problème est que tout le monde dit "Programmer votre code pour que cela puisse être évité" ... comme le champ distint dans DB ... Mais il y a beaucoup de ifs et Buts dedans. A partir de maintenant, je suis toujours à la recherche ... –

Répondre

1

La meilleure façon serait d'envelopper la forme dans un < asp:UpdatePanel>. De cette façon, toutes les publications sont effectuées via AJAX et le navigateur ne vous demandera jamais de soumettre à nouveau votre formulaire.

+0

merci cependant je reste loin des contrôles MS AJAX. – PositiveGuy

+0

Oui, absolument le plus facile! –

0

Les deux meilleures façons de le faire sont les suivantes:

  1. Exécution d'un contrôle sur un champ distinct contre la base de données

  2. Créer un jeton caché sous la forme qui utilise un sel en fonction du temps. Si vous placez la logique dans le script pour vérifier l'heure existante et la comparer au jeton, vous pouvez autoriser la soumission ou la définir. Par exemple, si le formulaire est dessiné à un certain moment, vous stockez le jeton, et dans les 30-60 secondes, vous pouvez soumettre, mais après cela, vous ne pouvez pas.

3

La solution que je l'utilise est le plus souvent ceci:

Lorsque l'utilisateur premières visites la page (non-publication automatique), génèrent une valeur symbolique (GUID est facile). Prenez cette valeur de jeton et stockez-la dans leurs variables de session et un champ masqué dans la page. Étant un champ, cette valeur devrait persister à travers des allers-retours au serveur sans ViewState activé (je pourrais me tromper sur ce compte, donc s'il vous plaît vérifiez-le!). Si la page est actualisée (et que les valeurs de formulaire sont perdues), une nouvelle valeur sera générée par l'initialisation Non-PostBack.

Lorsque la page est affichée en arrière, récupérer la valeur du champ caché et la comparer à la valeur attendue dans les variables de session de l'utilisateur:

  • Si les jetons correspondance, accepter la soumission comme « authentique », retirez-la jeton des variables de session et continuez votre flux de travail.
  • Si le jeton est manquant dans les variables de session, l'utilisateur tente à nouveau de soumettre le formulaire. - Si les jetons ne correspondent pas, l'utilisateur "rejoue" une ancienne soumission du formulaire.

code exemple pour réaliser ce genre de solution:

public partial class MyPage : Page 
{ 
    protected HiddenField tokenField; 

    protected void Page_Load() 
    { 
     if(!IsPostBack) 
      CreateToken(); 
    } 

    // Call this method to establish a token in session and on the page. 
    private void CreateToken() 
    { 
     string token = new Guid().ToString(); 
     Session["dupeToken"] = token; 
     tokenField.Value = token; 
    } 

    // Call this method to validate the token before continuing workflow. 
    private bool TokenIsValid() 
    { 
     string expectedToken = (string)Session["dupeToken"]; 
     if(expectedToken == null) 
      return false; 

     string actualToken = tokenField.Value; 

     return expectedToken == actualToken; 
    } 

    // Call this method when the page submission is complete to prevent re-submission. 
    private void ConsumeToken() 
    { 
     Session["dupeToken"] = null; 
    } 
} 
+0

Si vous appuyez sur le bouton Précédent et relancez la soumission, les jetons correspondent: comme tout autre élément de formulaire, le champ caché qui stocke le jeton d'origine reste inchangé. –

+0

Ils ne devraient pas, puisque le jeton est seulement généré lors de visites au formulaire où les valeurs ne sont pas présentes dans les champs (c'est-à-dire une soumission unique). Étant donné que le jeton est "consommé" dans Session sur une soumission, il ne sera pas présent pour les relectures du formulaire. –

+0

Le problème est ce bouton "Retour": lorsque vous utilisez le bouton Précédent pour naviguer vers une page à partir de laquelle vous avez posté, tous ses éléments d'entrée de formulaire (y compris les champs cachés) ont les valeurs que vous avez utilisées pour la publication originale. Par conséquent, le jeton d'origine est toujours présent lors de la nouvelle soumission de l'utilisateur. –

Questions connexes