I recently found out the hard way that the underscore character “_” can be problematic within URLs, particularly with Internet Explorer. Here is why…

(FYI, my testing was done with IE 9)

First of all, the underscore character is a perfectly acceptable character in a URL. Web browsers can deal with it fine in most circumstances. However, IE seems to dislike the underscore when it is in a domain or subdomain name, for instance www.my_site.com or test_site.mysite.com. Will it work? Under general circumstances it might. The problem shows up when you need a cookie for the site, which most sites do, especially if you are using cookies as part of your authentication scheme. IE can’t create cookies when the domain or subdomain name has an underscore.

This doesn’t seem to be a problem for Firefox (I’ve tried it) and Chrome (so I have heard).

A note about SEO

Also, it is worth mentioning that the underscore is not a good choice in a URL if you are interested in SEO. That’s because some search engines like Google don’t consider the underscore a word separator. To Google, it reads a URL like “mysite.com/Page_About_Something_Cool” as mysite.com/pageaboutsomethingcool” which won’t help your rankings much. Bing is fine with the underscore but of course simply using a dash “-“ instead will keep both search engines happy.

I’ll close with a few examples

www.somesite.com/page-with-content good choice for a variety of browsers and search engines
mysubdomain.somesite.com/page-with-content good choice for a variety of browsers and search engines
www.some_site.com trouble for IE with cookies
sub_domain.somesite.com trouble for IE with cookies
www.somesite.com/page_with_content valid but bad for SEO with Google
Posted in Web.

In trying to set this up, I kept finding articles and blog posts that had instructions that didn’t work. In the end, setting this up was pretty easy.

First off, I am running IIS 7.5 on Windows Server 2008 R2. If you have a different set up, this might not work for you.

First, the problem – a pretty common one:

We’ve got our Application Pools set to recycle once a day. However, each time the app pool recycles the first user to hit the site has to wait while everything warms up again. That wait can be 30 seconds or so which is a pretty long time. So I want my application to be ready all the time, even after an Application Pool reset.

Side note… I don’t recommend using the default settings for app pool recycling. If you do, the pool will recycle every 1740 minutes. However, that time could end up being in the middle of a busy day. That would be bad. Instead, I set mine to recycle at around 3 AM when no one is using my site. Of course, you may have different needs.

The Solution

Setup

IIS 7.5 has a feature called Application Initialization. I’ve seen many blog posts about it. Some say you can use the GUI to configure it. Some say you configure it via a .config file. Most of them imply that the feature is there and ready to be used. For me it was not installed by default and there was no GUI. I’m not sure why. Are my servers (prepared by a different team) configured to not have this feature? I don’t know.

In any case, installing this feature is easy. Just go here and install the Application Initialization Module for IIS 7.5. It is pretty quick but will require a reboot.

Once you do, open IIS and click on the server node and in the main window under Management, click on Configuration Editor:

image

Inside the editor, set the section (via the dropdown at the top) to “system.webServer/applicationInitialization”. If you can do that, the installation was successful! Prior to installing, that node wasn’t there! Interestingly, there are some settings here that imply you can change them via the UI. For instance, I tried setting “doAppInitAfterRestart” to True. Not only did that not help, it caused errors with IIS. So why is it there? I have no idea. My advice… don’t touch those settings.

image

Configuration

IIS is all set but now you need to tell it which app pools and websites you want it to start. Simply go to:

C:\Windows\System32\inetsrv\config

and open the applicationHost.config file. You may want to back the file up before you make changes.

You’ll need to add two things.

1. The App Pool:

Find the applicationPools node. Within it it you will find each app pool listed. Here is an example:

<add name=”YOURAPPNAMEHERE” autoStart=”true” managedRuntimeVersion=”v4.0″ startMode=”AlwaysRunning”>
<processModel identityType=”ApplicationPoolIdentity” loadUserProfile=”true” />
<recycling logEventOnRecycle=”Time, Requests, Schedule, Memory, IsapiUnhealthy, OnDemand, ConfigChange, PrivateMemory” />
</add>

Simply add the highlighted text startMode=”AlwaysRunning”. You will note that it probably already says autoStart=”true” but yet it didn’t autostart. Another misleading part of this, huh? Oh well.

2. The Web Site

Go to the sites node and find your site which will look something like this:

<site name=”YOURSITENAMEHERE” id=”4″ serverAutoStart=”true”>
<application path=”/” applicationPool=”YOURAPPPOOL” preloadEnabled=”true”>
<virtualDirectory path=”/” physicalPath=”C:\inetpub\wwwroot\YOURSITENAME” />
</application>
</site>

Once again, add the highlighted text.

Validation

How do we know it works? That is easy…

  1. Open up the task manager and go to the processes tab.
  2. Sort by Image Name and find the process w3wp.exe. There may be multiple instances. The Username should be the name of the apppool.
  3. If you try to End the Process, you will find that it restarts itself. Seems like it won’t go away ever. Uh oh, how do you stop it then?
  4. To stop the process you must stop the application pool.
  5. Of course, if you restart the app pool you will find that the w3wp process comes back. But wasn’t that what you wanted in the first place?

Problem solved. Enjoy.

One lesson I have learned over the years is not to take any unnecessary risks during production deployments. I hope that by sharing this wisdom I can help others, but I have the sad feeling that this one of those lessons that people need to learn the hard way. Unfortunately it is too tempting to “just go for it” sometimes. If it works, consider yourself lucky. When it fails (and sooner or later it will) you will regret your cowboy ways. I hope you will read on, there are some great ways to mitigate the risk of deployments.

Most of the problems that occur during deployments are caused by simple human error. Nothing serious, just plain old forgetfulness! In my experience, deployment issues usually arise because someone just forgets to do something. The thing that gets forgotten could be anything from a database script that gets missed, a forgotten view, an overlooked setting, or a .config file omission. And I don’t mean that this happens because someone is a bad developer. It’s just human nature. We are not perfect and can’t possibly remember everything.

There is no foolproof solution for perfect deployments. However, by following these tips you can greatly increase your likelihood of success. Of course, any of these practices will help but for best results, combine them all.

Deploy as often as possible

The best way to make sure nothing gets missed is to deploy often. Time is your enemy, the longer you wait, the more likely you are to forget something. During the development process we do so many things to make our applications work properly in our development environment. Sometimes we use a lot of trial and error too. As time goes on we can’t possibly remember all of the steps we have taken along the way. Following an agile process with short sprints is a great way to achieve short deployment cycles. Agile or not, try to deploy when features are complete and at major milestones. You don’t need to actually deploy to production. Use the same deployment process for all your environments. If you can’t deploy to production (there are lots of reasons for this), create a staging environment and treat it like production.

Take notes

Even if you deploy often, don’t rely simply on your memory. Take a lot of notes along the way during development and during your deployments to other environments such as test, staging, etc. Develop a good system so that your notes are there when you need them, not buried and forgotten in a notebook somewhere. I like OneNote for stuff like this.

Have a solid plan

Don’t wing it. Have a good, standard plan and stick to it. The more you follow the plan, the more likely you are to succeed.

Use a good code base

Of course, you only deploy code that you know works correctly, right? Once you know it works, don’t leave anything to chance. One of the best ways to do this is to deploy the same code to all your environments. Avoid going back to your source repository and recompiling. So many things can go wrong once you do. After you deploy to your test environment and everything has been verified, you should use the exact same files (.dlls, script files, whatever) and deploy them to prod (or your other environments). Of course you will be probably need to make configuration changes, that is often unavoidable.

Watch your timing

Find a time that works good for you and your team. Different businesses will have varying constraints on when they can do production deployments so you will of course need to work within those parameters. But I definitely have my preferences for when I would choose to deploy. I like to deploy first thing in the morning when I am fresh and thinking clearly. If something goes wrong, I have a lot of time to fix it. Also, I’ll have access to other people/resources for help if needed. If I deploy at the end of the day and something goes wrong I’ll be stuck working at night to fix it. That is bad because a) I’ll be getting tired and might not think clearly, b) I won’t have people around to help and c) I won’t get to have dinner with my kids. I also like to deploy midweek. Monday mornings are bad because over the weekend I have forgotten things already! Monday is a great day to put final preparations on a big deployment. Fridays are bad too. Because if things go wrong, I could be stuck trying to fix things over the weekend!

Automate your process

I don’t trust myself or my memory much. The best way I can protect myself from me is to automate my deployments. Once things are scripted, automated and tested, I have greatly increased my chances for success. Most of the other tips I have listed are fairly easy to implement, but putting together an automated deployment can be a big project all in itself! Depending upon your project, automated deployments can be quite complicated and there is a lot to learn in this department. There are lots of great build and automation tools out there to help such as MSBuild, NAnt, TeamCity, Hudson, CruiseControl, etc. I’ve used a bunch of different tools over the years and now I am using Team Foundation Server 2012. I’ve found it to be the easiest and fastest of all to set up for my web project deployments.

Practice your deployments

Practice makes perfect, right? Unfortunately with deployments, just when you get your process working smoothly there will be some big change that will require you to modify the process anyway. But practice will definitely increase your chance for success. I even practice my automated deployments, that is the reason to have a staging/faux-prod environment. And practicing really comes in handy when it comes to database changes. It’s great to have a staging environment set up just for the purpose of practicing deployments. To practice, get your staging environment set up to match your production environment including .dlls, html and script files, databases and other resources. Then run through your deployment process on staging. Once complete, test your application to make sure everything works. If something went wrong in the deployment, don’t patch it. The best thing to do is roll back the entire staging system, tweak your process and run it again. You do this as many times as needed until you get everything right. Then you are ready to repeat your steps in your production environment. Of course, the more you automate, the less likely errors will be. But don’t assume that just because you have an automated system you don’t need to practice too.

Start soon

Lastly, do not wait to implement this process. Many developers wait, thinking that they’ve got a long development cycle and won’t be deploying to prod for a long time, maybe months down the road. When I start a new project I begin working on the build/deployment automation right away. I also make sure there are tasks created for this process. Making this an official deliverable buys me time for this work which can definitely be time consuming. And if you don’t get this work done early, you might not get to it at all. When a project is almost complete and the delivery date approaches, you will never find time to get your process in place. You will then be stuck with an error prone deployment that not only keeps you worried but will likely cause you to work on weekends fixing deployment issues.

 

A solid deployment process takes a lot of planning and work. Of course, if you have ever been on the wrong side of a bad deployment you know that all the planning is worth the extra effort! Good luck.

 

Lately I’ve been speaking at local user groups about many of the exciting new features in Visual Studio 2012. Since there is so much to know and learn about VS 2012, I decided to create a collection of blog posts with many of the tips. This collection of posts will include features that are new to VS 2012 as well as some existing features as well. To view all of the VS 2012 tips posted so far, click here.

Visual Studio 2012 has got a lot of great features. Some of them are really innovative and interesting. I don’t think of the Add Reference Dialog improvements as anything but “why in the world did this work so poorly before?”. I’m guessing the Visual Studio team had some reason but let’s face it, the old Add Reference Dialog just plain sucked. One of the biggest problems with it was that it was very slow to load. I’m happy to report that the new Dialog loads really fast! Try it out, I am sure you will be please with the results.

Access it as you did before, right click a project and then click “add reference”:

image

Like I said, it loads up really fast. As you can see, in the middle section is the complete list of assemblies from the .net framework. Note that the items with checkmarks have already been added to my project. Just as you’d expect, you can add references to installed.net assemblies, other projects in your solution and COM Libraries. And of course, you can browse your system for other .dlls.

When you use this the first few times I expect your get bit by the same snag that I did (and still do sometimes). See the screenshot below… Notice that I clicked on Microsoft.Build to add the reference. You can see it highlighted in blue. If I click the OK button I’ll be disappointed with the results as my reference will not be added. What is needed is either to double click the item in the list or click the checkbox itself. Either way you’ll see the checkbox is then checked. Now you can hit OK. By the way, unchecking an item in the list will remove it from your project.

image

 

I hope you find this tip helpful. To see more VS 2012 Tips, just click here.

Lately I’ve been speaking at local user groups about many of the exciting new features in Visual Studio 2012. Since there is so much to know and learn about VS 2012, I decided to create a collection of blog posts with many of the tips. This collection of posts will include features that are new to VS 2012 as well as some existing features as well. To view all of the VS 2012 tips posted so far, click here.

I think (I hope) it is a well-known fact that Visual Studio will automatically complete your event handlers for you. The problem is, I’ve never liked the way it did this and I always went in and cleaned them up. Not any more!

What am I talking about? Here’s a sample. In this case, I have a class Foo that has an event SomethingHappened.

    public class Foo
    {
        public event EventHandler SomethingHappened;

        public void OnSomethingHappened(EventArgs e)
        {
            EventHandler handler = SomethingHappened;
            if (handler != null) handler(this, e);
        }
    }

In another class, I have an instance of Foo named foo. To wire up that event, all I need to do is type:

foo.SomethingHappened += [TAB][TAB]    (I hope you know that I mean hit the “tab” key twice Smile)

When you do that in Visual Studio 2010 (and prior), you will get the following results:

public class SomeService
{
    private Foo foo = new Foo();
    public SomeService()
    {
        foo.SomethingHappened +=new EventHandler(foo_SomethingHappened);
    }

    void foo_SomethingHappened(object sender, EventArgs e)
    {
        throw new NotImplementedException();
    }
}

What happened here? Visual studio added a method (foo_SomethingHappened) and attached it to my handler for me. Thanks!

But this gets even better when you use Visual Studio 2012! Doing the same thing will get you this:

    public class SomeService
    {
        private Foo foo = new Foo();
        public SomeService()
        {
            foo.SomethingHappened += foo_SomethingHappened;
        }

        void foo_SomethingHappened(object sender, EventArgs e)
        {
            throw new NotImplementedException();
        }
    }

 

OK, it isn’t thatdifferent. But the “new EventHandler” text is not there. It isn’t needed, of course so it rightfully isn’t there. I try to remove as much extra text from my code to make it more readable and I’m glad the Visual Studio team is thinking along the same lines. Actually, a lot of the time I clean this up even more by removing the object name from the event handler, in this case “foo_”. It might be needed sometimes, for clarity or, of course, if you need to specify which object the event is for. But in this case, I think it is just overly verbose. I prefer this:

    public class SomeService
    {
        private Foo foo = new Foo();
        public SomeService()
        {
            foo.SomethingHappened += SomethingHappened;
        }

        void SomethingHappened(object sender, EventArgs e)
        {
            throw new NotImplementedException();
        }
    }

I hope you find this tip helpful. To see more VS 2012 Tips, just click here.