[ASP.NET] Refresh zorgt voor tweede submit van gastenboek

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • NickThissen
  • Registratie: November 2007
  • Laatst online: 09-09 10:50
Hoi,

Ik heb een klein gastenboekje gemaakt in ASP.NET op mijn website. Het stelt niet veel voor, simpelweg een Repeater control die de naam en het berichtje onder elkaar plaatst.

Boven het gastenboek zitten een aantal input velden voor de naam, email, website en het bericht. Daar onder een knopje 'OK' om het bericht te plaatsen. Ik doe nog een check of de naam en het bericht wel ingevuld zijn, en als dat zo is sla ik het nieuwe bericht op in de database en herlaad ik de berichten in de repeater, zodat het nieuwe bericht getoond wordt.

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
    public partial class Gastenboek : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!this.IsPostBack)
            {
                lblMessage.Visible = false;
                this.LoadMessages();
            }
        }

        private void LoadMessages()
        {
            // Laad alle berichten
            repeater.DataSource = GuestbookMessageManager.Instance.Load();
            repeater.DataBind();
        }

        protected void btnOK_Click(object sender, EventArgs e)
        {
            string errorMessage = null;

            // Check of verplichte velden zijn ingevuld
            if (string.IsNullOrWhiteSpace(txtName.Text))
                errorMessage = "Naam mag niet leeg zijn!";

            if (string.IsNullOrWhiteSpace(txtMessage.Text))
                errorMessage = "Bericht mag niet leeg zijn!";

            if (!string.IsNullOrWhiteSpace(errorMessage))
            {
                lblMessage.Text = errorMessage;
                lblMessage.Visible = true;
                pnlEntry.Style["display"] = "inline";
                btnExpandEntry.Style["display"] = "inline";
                return;
            }

            // Zo ja, nieuw bericht maken en opslaan
            var msg = new GuestbookMessage();
            msg.Username = txtName.Text;
            msg.Email = txtEmail.Text;
            msg.Website = txtWebsite.Text;
            msg.Message = txtMessage.Text;
            
            GuestbookMessageManager.Instance.Save(msg);

            // En weer opnieuw laden
            this.LoadMessages();
        }
    }


Simpel genoeg, en het werkt ook allemaal prima.

Het probleem is nu, als je een berichtje plaatst en daarna de pagina refreshed, dan wordt hetzelfde berichtje nog eens geplaatst. Ik krijg wel (in Chrome in ieder geval) een berichtje dat er inderdaad acties herhaald kunnen worden als je refreshed, maar goed, een gemiddelde gebruiker zal dat niet lezen en gewoon op Ok klikken.

Wat kan ik doen om te zorgen dat het berichtje niet nogmaals geplaatst wordt?
Bedankt!

Mijn iRacing profiel


Acties:
  • 0 Henk 'm!

  • Niemand_Anders
  • Registratie: Juli 2006
  • Laatst online: 09-07-2024

Niemand_Anders

Dat was ik niet..

Je kunt in plaats van LoadMessages() in btnOK_Click ook naar jezelf redirecten zodat de bezoeker een GET request doet en dus geen dubbel post kan doen.

Voor regel 49:
C#:
1
Response.Redirect("gastenboek.aspx", true);


Dit is de meeste eenvoudige oplossing welke ik zo snel kan verzinnen. Er zijn betere methodes, maar die brengen van complexiteit met zich mee. je kunt aan het formulier als hidden value ook een guid meegegeven.
Bij de postback controleer je op deze guid niet voorkomt in de cache.Je voert je postback acties uit en slaat de guid op in de sessie. Komt de guid al voor in de sessie, dan heb je te maken met een dubbele post..

If it isn't broken, fix it until it is..


Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
^ Wat hij zegt: Wikipedia: Post/Redirect/Get. Als je toevallig al een bepaalde CSRF protectie gebruikt kun je ook bijvoorbeeld het toch al daarvoor aanwezige token gebruiken om te detecteren of de post al eens eerder gedaan is.

[ Voor 128% gewijzigd door RobIII op 29-07-2011 14:35 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij