ASP.NET


30
Apr

Why I hate web.config

One thing that is vital when deploying web applications is that you should be able to reduce the process of deploying upgrades and changes to as few steps as possible. Furthermore, every step should be a no-brainer — so simple that the scope for fat fingering something is strictly limited.

This kind of thing is acceptable:

  1. Get the appropriate stable build from your daily build server.
  2. FTP it onto the web server into a directory in an appropriate location. (Even better: have an option in your build script to do this automatically.)
  3. Change the IIS settings to point to the new version.
  4. You’re done!

Now in order to do this effectively, you need to build some foundations into your project. You need to isolate every setting that varies between your production environment and your developer box and put them in a separate location outside the website’s hierarchy that does not change from build to build.

These settings are purely concerned with server-specific configuration settings. They change from one machine to the next and will be different between developer machines and the production server. Examples include connection strings, SMTP server details, custom errors and trace settings. They aren’t necessarily stored in your source control, except as a sample file for documentation purposes, and they should definitely not be deployed afresh to the server with every build.

There are other settings that are tied much more closely to the code itself. Examples include HTTP handlers and modules, assemblies referenced in the <compilation> section, and all the additional stuff that ASP.NET Ajax or ASP.NET 3.5 adds to tell it that you’re using the C# 3.0 compiler, not the C# 2.0 compiler. These settings may change from one build to the next, but they are the same on every machine where they are used. They are, to all intents and purposes, code, and should be treated as such, kept in your source control, and deployed unmodified to the server with every new build.

Unfortunately, web.config mixes the two willy-nilly in a thoroughly cavalier way, with the result that there are several additional, more complex and error-prone steps that you need to take:

  1. Locate the previous build.
  2. Copy the web.config file into the new build.
  3. Merge in the changes manually.

These steps are less straightforward and provide much more scope for error. What if you forget to do them, make a dog’s dinner of merging in the changes, or worse, introduce some subtle and mysterious bug that isn’t there on your development machine?

ASP.NET 2.0 added a new feature to sort this mess out. You can now specify an alternative file for your <appSettings> section. By doing <appSettings file="..\myappsettings.config" /> you can even specify a file outside your web application root. Whoopee! Problem solved!

Not so fast. What about the settings that don’t fit in to <appSettings>? For example, connection strings now go in the <connectionStrings> section; custom errors should be enabled on the server but disabled on your development box; tracing should be enabled on your development machine but not on the server; and so on.

It turns out that these too have an option to allow you to reference external files. You can set, say, <connectionStrings configSource="blah" /> to put your connection strings in a separate file. Unfortunately, unlike with <appSettings>, you can’t put this outside your application root.

Meh. Why not??? This is a major pain in the neck — especially for <connectionStrings>.

To make matters worse, there are some elements that straddle both camps. <compilation> is the most obvious example. It needs to have the attribute debug="true" on a development server, but in production you will need to insert debug="false" for improved performance. However, within your <compilation> element, you have a list of additional assembly references for things such as the ASP.NET Ajax extensions. And you can’t put these in a separate file.

All in all, configSource and <appSettings file="blah" /> go some of the way towards solving the deployment problem. Unfortunately, they still have limitations that are awkward and hobble the process and are a major annoyance.

14
Jan

Missing ASP.NET tab in IIS on Windows Server 2003

One thing that’s been at the back of my mind since I upgraded to Windows Server 2003 is that the ASP.NET tab in IIS had taken a walk. Even running aspnet_regiis -i did nothing to solve the problem. Up till now I had no cause to fix it, but today I had to troubleshoot one of our apps that is (still!) using ASP.NET 1.1. This meant I needed to configure it to run version 1.1 in order to debug it using Visual Studio 2003. Might as well get to the bottom of this while I’m at it.

It turns out the problem is something to do with VMWare Server, which I also have running on the same machine, running a couple of instances of Ubuntu for my PHP work. For some reason this conflicts with the ASP.NET tab on Windows Server 2003. Fortunately, a quick Google search led me to this post, which has a fix described in the comments.

So, if you have the same problem:

  1. Stop IIS using iisreset /stop
  2. Open the file C:\WINDOWS\system32\inetsrv\MetaBase.xml in Notepad.
  3. Find and delete the line that says Enable32BitAppOnWin64="TRUE"
  4. Restart IIS using iisreset /start
  5. If you still don’t see your ASP.NET tab, aspnet_regiis -i should now work.
15
Oct

The point of certifications

I’ve decided to take some more .NET certifications. This time I’m after the MCTS (Microsoft Certified Technology Specialist) and MCPD (Microsoft Certified Professional Developer) qualifications in web applications, possibly with more — particularly SharePoint — to follow afterwards.

Some people seem to think that certifications are pretty pointless. They don’t have a great deal of an effect on your career, they say: real world experience is much more impressive. On one level this is true: your Microsoft certificate isn’t worth the paper it’s written on if you haven’t any experience to back it up. After all, any clown can learn by rote the stuff that they need to sit three two-hour multiple guess papers.

What I did find first time round, however, was that when you combine the study for the certifications with real world experience, and apply what you are learning to your work, your work actually benefits. You become a better developer, fill in some important gaps in your knowledge, and end up with an awareness and feel for the framework that you are using. As a result, you are less likely to end up reinventing the wheel with inefficient solutions or writing insecure code, and because you have a better knowledge of the framework at your fingertips, you can produce more code in less time with shorter development cycles. And I would disagree that it is worthless in terms of career advancement: it sends out a signal to management and prospective employers that you are keen to sharpen the saw and hone your skills.

I get the impression that some employers are particularly unwilling to provide any training and certification budgets, time or goals for their developers. Personally I think this is a travesty, because in most other industries, ongoing training is absolutely fundamental. Take school teachers for instance: here in the UK at least, they have half a dozen or so inset (in-service training) days. It is particularly pathetic when you consider that the world of IT and software development is one of the most rapidly changing industries in the world today, so ongoing training is all the more vital. In fact, it seems particularly strange to me that the Joel Test makes absolutely no mention of it.

Fortunately, I work for a company that is more enlightened.

27
Feb

Why doesn’t C# have a synchronized keyword?

In Java you can mark a class method as a critical section, i.e. it will only be executed by one thread at a time, by using the synchronized keyword:

synchronized void myMethod()
{
  doSomething();
}

In C# you have to type in this ghastly (and rather obscure) mouthful:

using System.Runtime.CompilerServices;

[MethodImpl(MethodImplOptions.Synchronized)]
void MyMethod()
{
    DoSomething();
}

Why can’t we have a synchronized keyword in C# for this like in Java?