Archive for November, 2009

Web Role as StartUp Project in Visual Studio

The other day I posted an entry about configuration files in Windows Azure, and I mentioned a strategy for being able to build a Web application that runs inside or outside of the cloud. I just wanted to follow up by mentioning the easiest way to test this; it’s one of those things that is so obvious you might not even think about it.

In a Windows Azure application, the “startup project” is set to the Cloud Service by default. So when you hit F5, the development fabric spins up, the service is packaged and deployed, a browser window opens to host your start page and the Visual Studio debugger attaches to the dev fabric process. But if you right-click your Web role, select “Set as StartUp Project” and then hit F5, Visual Studio will start a debugging session attached to the ASP.NET Web Development Server – in other words, outside of the development fabric. It’s a great way to test the dual-configuration approach I mentioned in my last post!

No Comments

Configuration Files and Windows Azure

Last week I posted a short article on how easy it is to move an ASP.NET Web Application to the cloud… and it is extremely easy, as long as you don’t have any data, configuration settings, 3rd party libraries, or other issues getting in the way! Actually, all kidding aside, it is pretty easy as long as you understand what’s different and what’s similar when you’re running in the cloud. With a little effort, you should be able to come up with a strategy that doesn’t force you to re-engineer your application; you might even be able to keep your Web application in a state that can be deployed to the Web or to the cloud without any configuration changes!

In this post I’d like to address configuration. If you’re an ASP.NET Web developer, you already know all about web.config, and you probably use it all the time to store configuration settings for your application. Let’s assume you want to store a simple message in configuration; your web.config file would contain the following:

<appSettings>
   <add key="messageText" value="Hello, ASP.NET!"/>
</appSettings>

Then you could write some application code that retrieves the value (in this case, displaying it on the Web page using an ASP.NET Label control):

message.Text = WebConfigurationManager.AppSettings["messageText"];

The good news is that Web applications running in Windows Azure support web.config so this code will work without any modifications whatsoever. The bad news is that when you deploy an Azure application, the web.config file gets packaged up along with the rest of the Web application components in a .csx file. This sort of defeats the purpose of putting your message in a configuration file, yes? If you didn’t need the ability to change the message without recompiling your application you could have just placed the message text directly into your code. So web.config is a great place for application settings unless you’re app is in the cloud…

Ah, but Windows Azure does support the idea of a configuration file – it goes by the name ServiceConfiguration.cscfg and it gets deployed separately from the .csx package. And, you can add your own custom settings to it, just like web.config. It takes a bit more effort, since you must first define the setting in ServiceDefinition.csdef:

<ConfigurationSettings>
   <Setting name="messageText"/>
</ConfigurationSettings>

…and then set the actual value in ServiceConfiguration.cscfg:

<ConfigurationSettings>
   <Setting name="messageText" value="Hello, Azure!"/>
</ConfigurationSettings>

Once you’ve done that, you can retrieve the value quite easily:

message.Text = RoleManager.GetConfigurationSetting("messageText");

If you’re moving your application into the cloud and you’re “not looking back,” it may make sense to move your settings into the .cscfg file and use that exclusive of web.config. But what about building an application that can be deployed in AND out of the cloud?

Fortunately, it is not difficult to determine at runtime whether you are running in or out of the cloud and retrieve configuration settings as appropriate. In the following code, note how we can check the RoleManager.IsRoleManagerRunning property:

if (RoleManager.IsRoleManagerRunning)
{
   // we're in the cloud
   message.Text = RoleManager.GetConfigurationSetting("messageText");
}
else if (System.Web.HttpContext.Current != null)
{
   // we're NOT in the cloud, but we're still in a Web application
   message.Text = WebConfigurationManager.AppSettings["messageText"];
}
else
{
   // not in the cloud, not in the web... desktop app maybe?
   message.Text = ConfigurationManager.AppSettings["messageText"];
}

As you can see, we’ll get the value stored in .cscfg if we’re running in the fabric (the cloud), we get the one from web.config if we’re a “regular” ASP.NET Web application and we can even fall back to the standard .NET Configuration manager.

One more thing – checking RoleManager.IsRoleManagerRunning all the time will surely get tedious if you have a lot of settings to retrieve. You may want to encapsulate the settings retrieval into a reusable component, perhaps similar to the following:

public class SettingsManager
{
   private static Settings _settings = new Settings();
   public static Settings Settings
   {
      get
      {
         return _settings;
      }
   }
}
public class Settings
{
   public string this[string key]
   {
      get
      {
         if (RoleManager.IsRoleManagerRunning)
         {
            return RoleManager.GetConfigurationSetting(key);
         }
         else if (System.Web.HttpContext.Current != null)
         {
            return WebConfigurationManager.AppSettings[key];
         }
         return string.Empty;
      }
   }
}

You can find a much more comprehensive example (one that also deals with logging) in the HelloFabric sample that ships with the Windows Azure SDK.

, ,

6 Comments