Blog Stats
  • Posts - 24
  • Articles - 0
  • Comments - 61
  • Trackbacks - 92

 

HTTP GET Idempotence and ASP.NET

I am struck by the consequences of the experience Craig relates in this post:

http://staff.develop.com/candera/weblog2/CommentView.aspx?guid=54fd1ed8-ea12-4555-9ee3-4f9e3d57907e

He is discussing a Wiki site that mysteriously had its page content rolled back to a previous version.  Wiki pages generally contain a link to do this, and it is assumed that a human would follow it with caution.  Turns out that GoogleBot crawled the site and what-do-you-know the content rolled back.  The underlying problem was that a GET request caused a significant side effect, in this case altering the content of the linking page. 

The HTTP specification recommends that GET requests are idempotent, which means that a given action is performed once even if it invoked numerous times.  The intent is that GETs are “safe and repeatable”.  That is, it should be safe for a crawler to invoke any GET request (subject to authorization of course).  

This bears on the question of how to best use ASP.NET controls, notably the data controls where you might attempt to optimize ViewState by eliminating postbacks and changing buttons to hyperlinks.  Note that the LinkButton is safe because it causes a postback.  You can also probably get away with using a form with method=GET because a spider is unlikely to submit a form (even one based on GET), but I don't recommend it.

I traditionally replace postbacks with links to optimize ViewState, as opposed to “simply” disabling ViewState, because a race condition exists if you do not have a DataKeys collection that is consistent before and after the postback.  The race is that the resultset might have changed in the meantime, and the action would thus be carried out on the wrong data key.  That is, you would be operating purely by ordinal.  So, with this idempotence revelation I am back to square one with optimizing DataGrids. 


Feedback

# re: HTTP GET Idempotence and ASP.NET

Gravatar I prefer links instead of postbacks. First, they work for all browsers, and small devices and phones are becoming more common. Next, the race conditions with postback/viewstate are very common and quite serious. I can't count the number of times I've approved the wrong post on the ASP.NET forums due to this very type of issue. If the ASP.NET forums can't get it right, do you really think your common developers can? This is very common among any high-use ASP.NET apps, although no one ever seems to acknowledge it. And its so easy to fix by using links, which also can allow you to avoid using response.redirect, let alone server.transfer which is terrible in the state it leaves the browser history. Speaking of history, links also allow you to set favorites, and also allow your users to use the back button. Hmmm, so links work in all browsers, give better consistency, allow setting of favorites, don't confuse history, and support the back button . . . Its just amazing to me that so many people have just bought into the postback model for so much. Yes, its great for events when you need them, but that doesn't make it a panacea for all things. And to your original issue -- I'd hardly call that a reason to avoid links -- that's just a reason to avoid stupid links, or at least unsecured stupid link! 5/26/2004 4:15 PM | Paul Wilson

# re: HTTP GET Idempotence and ASP.NET

Gravatar I agree with you that links are great for many reasons. It definitely simplifies development in many cases. The Wiki problem is interesting though, because the whole idea of a Wiki is that an anonymous user can edit the content. I suppose a trivial login page (with well-known credentials) or other scheme could stop a spider but allow a human. Nonetheless, the problem needs to be considered and understood even if it is an edge case.

Postbacks within DataGrids do not exhibit the race condition if ViewState is enabled and the DataKeys collection is used. Another solution is to persist the DataKeys collection outside of the DataGrid control itself; in that way ViewState can be disabled for the grid as a whole but the keys are tracked. 5/26/2004 5:42 PM | Eron Wright

# re: HTTP GET Idempotence and ASP.NET

Gravatar I've never heard of this DataGrid race condition issue. Can you post some references where this is discussed in detail?

Thanks 5/27/2004 5:57 AM | Jiho

# re: HTTP GET Idempotence and ASP.NET

Gravatar I don't know if "race condition" is a good description, but I went with that term since that was what Eron called it.

Basically, if you disable viewstate, which is common on grids since the viewstate is so large, then things can get out of sync if data is changing. The postback simply says to do something (approve or delete or whatever) a certain item in the grid by its position -- and that position may not be the same if the data has to be requeried! I've actually even deleted the wrong post in the forums because of this. As Eron noted, there are other solutions, although most people either have very large viewstates with grids, or disable it and potentially get things out of sync. 5/27/2004 7:23 AM | Paul Wilson

# re: HTTP GET Idempotence and ASP.NET

Gravatar Sounds like the problem is assuming that the position in the clients HTML maps to a position in some record set. Maybe better to perform commands based on item ID rather than position. 11/19/2004 1:10 PM | Brad

# re: HTTP GET Idempotence and ASP.NET

Gravatar I gave up on DataGrid for exactly this reason (and others).
I built an javascript class that handles client-side selection (with post-back persistence), and batch operations. Everything is keyed, not indexed, so no worries about deleting the wrong item on a post-back.
Instead of rendering out a table control directly, I render out inline javascript calls for each row.

mytable.row(348539, "Blog Title", "Mar 5, 2007", true);

This results in a page that is 1/8 the size! (not even including viewstate!)

Customizing the rendering and behavior of the grid is easy, and can be done with an extra .js file, which overrides the "row" method rendering.

The output is so compact, that I can afford to display 10 times as much data, and allow the user to "scroll" instead of "page" (paging is also available if needed)

The grid also supports nested grouping, and can be used as a treeview.

Email me at nathanaelDOTjonesATgmail.com if you would like a copy of the source code.




10/23/2007 12:28 PM | Nathanael Jones

# re: HTTP GET Idempotence and ASP.NET

Gravatar I will be your loyal reader. 10/19/2009 10:11 PM | tiffany key ring

Post a comment





 

 

 

Copyright © Eron Wright