Came across an interesting case a few days ago to do with ViewState. (OK, I know some people will say don't use ViewState ever, but humour me)

Create a page on it with two buttons and a label, which we'll call lblCounter.

  • Button 1 will simply post the page back
  • Button 2 redirects the browser to another page
  • The label shows the current value of a counter stored in ViewState

The codebehind this page is a follows

Protected Sub Button2_Click(
  ByVal sender As Object, ByVal e As System.EventArgs)
  Handles Button2.Click
End Sub

Protected Sub Page_Load(
ByVal sender As Object, ByVal e As System.EventArgs)
Handles Me.Load
ViewState("Counter") += 1
lblCounter.Text = ViewState("Counter").ToString()
End Sub

Run this little page and, as you would expect, the counter returns 1.

  • Hit button 1 and the counter goes up - yay!
  • Hit button 2 and then hit a link (not the back button in your browser) on that page which links back to the original page and the counter is reset to 1 - also yay!

Now for the interesting bit. Hit button 1 a few times and then click refresh on your browser. You get a dialog asking if you want to resend the information to get the page in order to refresh it.

  • If you click Cancel, nothing happens and the counter isn't incremented. It hasn't posted back to the server.
  • If you click Retry, the counter still isn't incremented even though it has posted back to the server which isn't what you'd expect, is it?

The clue is in the text of the dialog. It is resending the information used to bring this instance of the page into the browser. Let's suppose the counter on the page is set to 4. When refresh is pressed, all the http post data, which includes the ViewState from the previous instance of the page (counter = 3) is sent to the server again and when the server runs Page_Load it gets handed the previous value of the counter (3, not 4 as you might expect) and increments it as instructed in Page_Load (to 4 and not 5).