Wednesday, February 9, 2011

Why ASP.Net?

At work, I've been an ASP.Net developer for several years now. It's an easy platform to get started with. It seems its original purpose was to approximate desktop applications. To the degree it does that, it has succeeded. I'm going to argue in this post that approximating desktop applications obscures the true nature of the web and in the long run makes web programming more difficult.

In addition to ASP.Net, I also have experience in non-.Net web environments. Before my .Net days, I did some classic ASP. I've also created a Ruby on Rails site for my wife's father (Hiller Enterprises). So I get that the underlying model of the web is very different from the postback model of ASP.Net.

(note: this post only concerns traditional ASP.Net and not ASP.Net MVC)

This underlying model of the web is to take a request from a browser and return to it a response. Typically, this response will be HTML. The browser will then  interpret and display the HTML in a meaningful way.

The request sent to the browser will be either a GET or a POST. By convention, a GET is something you do when you want to "pull" data from a site. By virtue of that fact that you are reading this blog post, your browser did a GET to view it. A POST is what I did when I published this article to the web. I POSTed the text you are reading to blogger.com.

When you do a POST on the web, what you are doing is clicking on a submit button which happens to be nested within an HTML form tag. That is how a POST is triggered. That is the only way a POST is triggered. (Well, except via Javascript. Using Javascript you can set the "click" event on a element (eg an anchor tag) to trigger a submit. That is how ASP.Net Linkbuttons work.)

A typical form with submit button


OK, so now we know how to trigger a POST, but where does the form's data go. It goes to the URL specified in the form's "action" attribute. The web server connected with that URL then runs code to do the action the user intended using the form's data (e.g publishes a blog post).

Often in a PHP, Ruby, Python, Perl, etc environment you will see multiple forms on a page. This is because pages can get complex enough for the user to do multiple things on a single page. Cool! So you can Login or Logout or Add to Cart or Change your Facebook status all from the same page.

So what is different about ASP.Net? Well, ASP.Net uses what is called a server-side postback architecture. ASP.Net pages are restricted to just one form element. The action for that form always points back to URL corresponding to the page it is in. In other words, clicking on a submit button on a page POSTs the page back to itself.

So given a page with multiple buttons, how can we tell which button was clicked? Well, that is done via hidden input element on the page with the ID of __EVENTTARGET. It is set via Javascript right before the submit occurs. When the POST request reaches the web server, based on the value of the __EVENTTARGET field, the ASP.Net framework fires the corresponding event. It is up to the programmer's code to handle the event that was fired.

An ASP.Net form



So given these complications, what is the advantage of ASP.Net? Why would anyone use it?

I've distilled that answer down to one word.

ViewState

Yep, that's it. ViewState is the only advantage. Everything else can be done just as (or more) easily in traditional web programming.

For those who don't know, ViewState is a magic hidden variable put into every ASP.Net page. It contains a Base64 encoded string of key, value pairs. Each key, value pair corresponds with every HTML element found on the page. As you might imagine, it can grow very large.

A typical block of viewstate




Its purpose is to maintain page state throughout postbacks. So if you can imagine a desktop application, the data in the fields is always preserved after any button is clicked. Viewstate is the mechanism to emulate that in the ASP.Net world.

So the programmer can set the fields once when the page is first requested (on the GET) and ASP.Net will continue to re-populate them every time a user clicks a button on the page (which causes a POST). This is fairly convenient especially for the novice programmer. You don't have to re-pull the data from the database every time the page is posted back.

In my opinion, this convenience breaks down upon closer inspection. If Viewstate didn't exist, the web programmer would simply need to explicitly redirect back to the same page after a submit. In general, this might not be a bad idea since it re-requests the page as a GET instead of a POST. This allows the user to refresh the page without getting the dreaded POST warning popup.

The dreaded POST refresh warning

I've also made a claim that everything else can be done just as or more easily in traditional web programming. What exactly do I mean by that? What constitutes everything else? The list I'm thinking of is Javascript and AJAX, Restful URL representation, HTML validation, and CSS.

Javascript is famously difficult to code in ASP.Net applications. The primary reason being that the server side IDs for ASP.Net presentation controls (eg Textboxes, Dropdowns, etc) change once those controls are rendered as HTML. In the ASP.Net form example above, "txtName" is the ID the programmer gave to the Textbox. "ctl00_MainContentPlaceHolder_txtName" is the ID rendered in the browser. In other words, "ctl00_MainContentPlaceHolder_txtName" is the ClientID. Since there is only one form on the page, this "namespacing" of IDs is necessary to keep them unique.

This limitation can be worked around. However, it often restricts you from keeping all of your JS code together in one place on the page. Thus, debugging JS is monstrously difficult in ASP.Net.

Likewise, CSS is difficult for the very same reason. It often causes you to create more markup than you actually need. For example, if you want to style something by ID in CSS (using the # prefix), this element cannot be a "server" control since its ID must not change. If you also need to manipulate it on the server, you'll have to create a wrapper server control around said HTML control. You now have markup that only exists to get around framework limitations.

ASP.Net applications are not easily made Restful. In fact it is usually easy to spot an ASP.Net application since the "page" part of the URL ends in .aspx. A typical Restful URL might look like:

/posts/1

In ASP.Net it would look something like:

ShowPost.aspx?id=1

Another near impossibility is HTML validation. That is because if you use Microsoft's out-of-box controls such as Textbox, Linkbutton, Hyperlink, etc, you have no control of the resulting HTML sent as the response to the browser. So if you want your HTML to be valid you have two choices:

1) Only use native HTML controls instead of Microsoft's ASP.Net controls
2) Create your own server controls based on Microsoft's controls

Either option is viable but requires a substantial time investment to perfect.

So given what a horrible piece-of-crap ASP.Net is, is there ever a good reason to use it? In a word, CRUD applications. Essentially, ASP.Net is the web equivalent of the Microsoft Access database. If you need to quickly create a big form of data with a couple of buttons on it for users to save records, ASP.Net is better than the other frameworks (Maybe). If you are developing a site for the public internet, do not use ASP.Net. Virtually every other option is both easier and better.