Having used ASP.NET for the last several months has had it’s ups and downs, but there are some issues in particular that haven’t just been annoyances, they’ve actually surprised me. Moments when although I’m working in a modern environment -the latest and greatest- I felt like I was stepping back in time several years. These are the biggest hitters.
1. Deployment
ASP.NET features an xcopy deployment, which is nice. It means that you should be able to copy your app from one machine to another, restart a service, and you’re deployed. (Just like you can with Ruby on Rails, PHP, Java, Python…). But, here’s the kicker… and it’s the kind of thing you take for granted when working on a Linux environment:
- Windows has no equivalent to scp for copying files from one server to another. You need to install an ftp server on the target machine, and poke the appropriate holes in Windows Firewall just to give yourself the ability to copy files to the target machine.
- Because you’re using ftp, you need an ftp client, which in the case of Windows has limited scriptability. You can feed it commands with
-s
and a text file, which means you need to hardcode your ftp information in a text file if you want a scripted deployment. - The built-in ftp client also doesn’t support compression of data over the wire, which means that if you want any sort of speed, you’ll want to zip your source files before sending them. Windows does not include a command-line zip tool, so most people install a program like 7-zip.
- Once you’ve got your script set up to compress and copy files to the target machine, you’ll soon realize that because windows has no equivalent to ssh, you’ll actually have to get onto the production box to unzip the files you uploaded, copy them into place, restart services etc.
In the Rails world, all of this is done via one command, remotely: cap deploy
. This works because the OS has all of the supported underpinnings to make it simple. In a Windows world, these features are not present out of the box, and you have to do considerable custom work to end up with a deployment that is still more complicated.
My understanding is that PowerShell is supposed to help with some of these things, but I have not seen any evidence of it being able to run the full gamut of operations required to do what cap deploy
does (and I presume that if it could, it would have been released as a project of it’s own by now).
2. LINQ… you can’t spell CRUD without “U” and “D”.
Aside from the fact that it’s syntax is hard to get used to, I like LINQ as a query language. It’s powerful and gives you free typechecking and autocompletion. LINQ to SQL, while I think it excels at Creating and Reading data, really falls down when it comes to Updating and Deleting. LINQ to SQL has two “modes” for working with data – connected (when the client is rich and can send C#-native objects back and forth to the model layer) and disconnected (when data has to be serialized/deserialized or clients can be gone for a long period of time). The web environment is technically disconnected.
The problem is that the LINQ to SQL framework really doesn’t handle this well. Updates and deletes require you to be connected to work in a logical way, so if you’re in a disconnected setting (which is everyone using ASP.NET) you have to either fake being connected – by re-querying your data before doing a delete/update – or hack around with workarounds and 3rd party libraries. The very basic scenario of “DELETE FROM User WHERE Id=5” does not exist in LINQ. It exists in every other ORM system I’ve ever used as a basic function.
3. Frequency of updates
To piggy-back on the last issue, you might notice that the article written by people concerned with this behavior was written in 2007. Over a year and half ago, now. The next version of .NET, which may or may not include fixes to these behaviors, doesn’t yet have a target date, AFAIK. Assuming it comes out this year, and assuming it does have better support for disconnected objects (ie. everyone doing web development) means that these behaviors will have been resolved more than 2 years after they were reported. By comparison, it took Rails 15 months to get from it’s initial public release to the 1.0 milestone. 12 months later was the dramatic 1.2 update, and 12 months after that was 2.0.
In addition to being able to deliver substantial new releases at nearly twice the speed, because it’s open source, there were tons of plugins available for it, and if you had a problem (as I did at one time with the speed of rendering RJS templates) you could get a quick fix from another person with the same problem, or just grab the patch for the problem before it made it into the next release (which we did with this one). At the time, I took this for granted. I now miss it a lot. There are 5-line fixes like this which, unless you’re open source, remain locked up and unattainable until the next major release.
4. Unit/Functional Testing
People have been able to cobble together some pretty good testing solutions for ASP.NET. I too have been able to get it to around 80% of where I’d like it to be. Aside from the fact that one would like to see these options better integrated (ala Rspec + Rails) there is still one fundamental aspect of unit testing that you’re completely on your own for – and that’s test fixtures.
Personally, I prefer to keep as much logic as possible out of the database, but no matter what you do, some logic is going to be there. Datatype checking, duplicate key constraints, null checking, etc. at a minimum. Unless your unit/functional tests are using a database, you’re not testing these aspects of your app. If you put more logic in your DB (stored procedures, triggers, UDF’s) that’s even more code you’re not testing. So, to write a complete unit test, you’re going to have to hit the database. For that, you’re on your own. There is no, to my knowledge, database fixture management for .NET. You just code up your own inserts/deletes for all of your tables. Thankfully, the xtunit plugin for nunit will get you rollback support for your individual tests.
I also miss having the ability to run functional tests without having to open a web browser. Watir is quite good, but the fact that it requires a browser, web server, etc. makes it a big pain to automate (ex. put it into your build process).
Good post. Any highlights?
The biggest highlight has been the performance. It didn’t take long with Wishlisting for me to feel like we had to cache wishlists for performance to be tolerable. Wishpot, by contrast, caches very little. I feel like you can stack a bunch of controls on a page and have it still be peformant, vs. a Rails page loaded with partials starts to slow down. I haven’t done any formal testing on this, but that’s how it has felt to me.
Debugging is also much better in .NET.