This won’t be news to most people who work with ASP.NET, but after a few days of frustration I had to write about it.

ASP.NET is fundamentally flawed. The flaw is in using form POST to do all of the work. Take, for example, the GridView control.

  1. Create new web project, open the Default.aspx page designer.
  2. Add a SqlDataSource that will return more than twenty records and a few sortable columns.
  3. Add a GridView and set its DataSource to the SqlDataSource. Enable Paging and Sorting.
  4. Run the page.
  5. Sort on a column
  6. Choose a different page of data.
  7. Click the browser’s Back button.

You’ll receive a warning message about resending POST data. This shouldn’t happen. I’ve done nothing to update data on the server. All I’ve done is request data.

Here’s another example. What if I create a page with a Search text box and a Find button? Upon clicking Find, I’ll display results on the same page so the user can search again. If I do as Microsoft intends, I’ll add code to the button’s Click event and update something like a repeater control. And then, if I browser Back, I get the warning message again.

In both of the above cases, a GET request should be used. POST is used when the user’s request is to change data. For instance, when submitting registration information.

But ASP.NET by design puts all actions into a single form POST. It uses forms to store all state data. You can construct code that performs GET, but that isn’t how things work by design.

Microsoft adds an attribute called “runat” to any control, whether its own or the standard html tags. <asp:Textbox Id="txtName" runat="server"><input type="text" id="txtName" runat="server">

When runat = “server”, three things become true. First, from a programmer’s point of view, the control essentially becomes a variable that you manipulate from code. The variable’s value (such as a text box’s text), is eventually sent to the browser as the response.

Second, on the server, ASP.NET will rename the id property of every control, for use in the view state. This means you cannot use css or javascript in the standard way.

Third, the control’s contents are stored in a hashed form in a page <input> variable. This means that the form’s entire state is stored in the page. Why not? Why not store state on the page so it can be returned each time?

The reason is that you must choose whether to return that state as part of a GET or POST. A GET will pass the state in the URL as a query string, which has limited allowed length. The advantage is a GET doesn’t trigger a warning on browser Back. A POST doesn’t have a length limit, but has the warning. Microsoft chose POST.

Microsoft has attempted to make http an event-driven protocol. This is fundamentally not the way the web works. The problems with misusing form POST are indicative of their flawed approach.