ASP.NET Sucks Huge Balls, And I Hate It

Now that I've got your attention...

Full disclosure: I make my living as a PHP programmer. So I can cough to the tribal bias right off the bat. I'm also a big fan of Open Source. That aside, I've had the misfortune to have worked briefly on ASP.NET projects in the past, and am currently contracting for a company - a PHP shop - whose own super-fine PHP-based website is being redeveloped externally for political reasons, by a sister company versed only in ASP.NET. We're about to take custody of that site as it if were our own spawn; needless to say the fireworks have already begun in earnest. So here's my take on some of the problems with ASP.NET.

I'm going to tackle this in two bites. Firstly a general look at why I find ASP.NET so abhorrent from my POV in the PHP camp, then a focus on a more specific gripe that came up this week: ASP.NET's inability to produce markup that conforms to XHTML 1.0 Strict (or, in many cases, Transitional).

I should make one more thing clear from the outset: I'm willing to believe that ASP.NET can be made to be great (or at least passable) if implemented with suitable expertise. My problem, however, is that I've been dealing with supposed ASP.NET "veterans" who still produce awful sites. It seems that the level of expertise required surpasses that of other for-the-web languages, because the stock products that pop out of Visual Studio and Visual Web Developer, wielded by those with less-than-savant ability, are just so very far from acceptable. Visual Web Developer in particular - though I know its use is held in less than high esteem by ASP.NET pros - seems to delight in churning out really awful sites. This is also not meant to be a shining appraisal of PHP - a language that I know is not without its faults - just a comparison along the lines of "it can be so simple in X, why can't it be in Y?"

Firstly the infrastructure as I see it. Anyone with a little skill can set up a perfectly production-ready web server without spending a penny on software, and on fairly modest hardware. All the components of the LAMP stack - Linux, Apache, MySQL and PHP - are available for free along with the support of great communities. Contrast ASP.NET, which requires a licensed copy of Windows/Windows Server + IIS, and a license for SQL Server. And let's not forget the development environment, which for nontrivial projects requires a further license for Visual Studio. Proprietary IDEs exist for PHP, sure, but I've never known any PHP developer have any issue with writing code in a simple, plain-text editor, perhaps with some syntax highlighting thrown in if they're lucky.

I'm not going to be so trite as to bust out figures here, but nobody can argue that - on the software side at least - the cost of using PHP is zero, while the cost of using ASP.NET is decidedly non-zero. Other people have done TCO comparisons ad nauseum.

Lastly, while I won't go down the "proprietary software is evil, OSS for evah!" route here, it has been pointed out that ASP.NET represents a dependency on one company, and the inherent liabilities therein. Regardless of where you stand on that issue (I'm going to helpfully sit on the fence for this one), the following situation might amuse: as mentioned above, the company to whom I contract is having their site developed by an ASP.NET shop sister company, who is then handing over the finished product for my employer to continue maintenance in the future. The sister company uses Visual Studio 2005; we can only purchase Visual Studio 2008 as Microsoft no longer offers older versions for sale. Once Visual Studio 2008 has opened and saved a .NET project, it can't be opened in older versions. So immediately we have a backwards-compatibility problem if the original authors of the codebase need to get involved in the future (as they inevitably will for support issues). Either they don't get involved or if they have to, they're effectively forced to upgrade to Visual Studio 2008. Ouch.

Various ground-level issues continue to irritate me. While PostBack can arguably be a useful device, its use brings multitude issues in otherwise simple situations like changing between the tabs on a tab strip control. The browser is loading a new page each time, but because every transition takes the form of a POST request, hitting the Back button in the browser results in the ugly "Are you sure you wish to re-submit this page?" dialog that completely breaks the UX. I'm told that IE has some additional support that allows ASP.NET to manipulate the history states, but that leaves non-IE users high and dry. And we all know which direction that demographic is going in.

I've also found issues with having multiple forms on one page - ASP.NET doesn't distinguish one from another (since the page is treated as one massive form), so hitting Enter in a text field to submit it will often submit a different form on the same page, or just reload the page in place.

PostBack and ViewState also spell trouble for meaningful/memorable URLs, as huge hashed values are passed from page to page making debugging from the browser end a complete nightmare. The site that I'm being subjected to at the moment has no friendly URLs like ViewItem.aspx?id=1234, instead passing all parameters in POST or using ViewState-style hashing to produce links with URLs like ViewItem.aspx?wEPDwUBMGQYAQU
. I'm sure these things make more sense if you're a seasoned ASP.NET pro, but from my POV as an experienced PHP developer I just cannot understand why these are the standard ASP.NET way of doing things, and how they can be said to be better than the straightforward, debuggable PHP equivalent.

Now for that other issue - spec compliance. This week I have been faced with the task of making the front page for my employer's new site (built by the ASP.NET shop) validate against some kind of sensible specification. We provided them with (valid) front-end HTML which then had ASP.NET components spliced into it. I thought I'd go for gold and try validating against XHTML 1.0 Strict. That failed dismally, as did Transitional. And here's a taster as to why, and why I still haven't been able to get successful validation even after finding this stuff out.

ASP.NET uses a scheme of assigning just about every element a unique ID. These IDs can't be relied upon to be consistent at runtime, so you have to refer to everything using classes if you want to get your CSS applied properly. That's one gripe. That aside, ASP.NET insists on giving every <form> tag a name attribute, the same value as its ID, but which breaks the Strict spec that dictates that forms cannot have names. There doesn't seem to be any way to suppress these attributes, meaning validation failure.

Second, we found that some of our image tags were failing validation due to having no alt attribute. Quite rightly, we thought - of course they should have at least an empty alt="". So we checked the code - ASP:Image controls in this instance - and found that they did indeed have AlternateText="" in their declarations. Turns out that if AlternateText is empty in the ASP.NET code, it is helpfully assumed that you didn't mean to put that attribute in, and no alt attribute is written in the HTML. Great.

Yes, I'm well aware that images should have meaningful alt values, but that's no excuse for this behaviour. There are situations where empty alt values are appropriate, but apparently not in ASP.NET's world, where it's more appropriate to violate the spec completely instead of just half-heartedly.

Finally there was an instance where we had an ASP:ImageButton being used to submit a login form. The validator was complaining about the tag generated by this control, saying that the border attribute was not allowed (on an input type="image" field). Fair enough, we thought - we looked at the ASP.NET code, but could find no evidence of a border attribute being specified at all, even under some different name. We then looked in the HTML, and found no border attribute either. What we did find was a style attribute, which looked like style="border-width:0px". Confused? You bet. Further investigation revealed that ASP.NET was writing the invalid border attribute out in the HTML, then using JavaScript to change the DOM at the point of page load, replacing that attribute with the style attribute above. Why? Who knows. Of course the validator doesn't support JavaScript, so it sees something different to the browser, and the spec is violated again. Once again, we seem to have no control over this behaviour, making it impossible for our page to pass validation.

Now look. I'm not suggesting these problems are completely insurmountable. A bit of searching has revealed that some of these problems could be addressed if we (or our sister company) were to use the ASP.NET 2.0 Web Forms extension, or even write our own controls that produce valid code. But what I'm saying is that we shouldn't have to resort to that; that if ASP.NET really is the all-singing, all-dancing super web platform of the future, this sort of thing should be handled properly by default and shouldn't take a genius to figure out. I'm also prepared to be told that our sister company are morons - same logic applies.

I'm prepared for unending flaming from the ASP.NET crowd, but I'm hoping for some constructive comment. From where I'm standing, PHP might not be the perfect solution, but I'm damn sure I can build great websites with it, relatively hassle-free. My experience thus far with ASP.NET doesn't fill me with a great deal of confidence. Is it really that shit, or have I just been watching the work of idiots? If it's done right, does it turn out anything like this?