Home > Windows Azure > Portable Configurations for Windows Azure and Local IIS

Portable Configurations for Windows Azure and Local IIS

We were involved in migration an ASP.Net web application with SQL Server as backend to Windows Azure and SQL Azure. In this application, we wanted to perform functional and basic integration testing on local IIS server (not Azure Emulator but the IIS Server) and after the basic validations wanted to deploy the web application to Windows Azure.  In the process the basic requirement was to do this with minimal or no change in the code or configuration. So the problem statement:

Provide a portable mechanism for ASP.Net web application to run on local IIS connecting to on premise SQL Server and with minimal or no changes to code/configuration files, the same application should be able to deploy and run on Windows Azure connecting to SQL Azure database.

So, before jumping to the solution let us first drill down to the problem statement a bit. Basically, to achieve this portability between IIS and Windows Azure the configuration settings are the items of concern.  We could develop a custom configuration manager responsible for returning the respective configuration value to the caller depending on the environment (IIS/Azure) it is running on. 

We could replicate the appsettings from web.config to serviceconfiguration.cscfg file in cloud project. As the connection strings being used in the project are required to be in web.config we wanted a mechanism to select local or SQL Azure connection string depending on the whether it’s running on local IIS or on Windows Azure.

Below is the static method we implemented in a utility class (PortableConfigurationManager) to achieve the retrieval of configurations from the configuration files either web.config or serviceconfiguration.cscfg.  Basically it checks whether the RoleEnvironment.IsAvailable or not and accordingly it is going to return configuration values from either .cscfg or web.config.

        public static string GetConfigurationValue(string configurationName)

        {

            if (RoleEnvironment.IsAvailable)

            {

                return (TryGetConfigurationSetting(configurationName) == null) ?     TryGetAppSetting(configurationName) : TryGetConfigurationSetting(configurationName);

            }

            else

            {

                return TryGetAppSetting(configurationName);

            }        

        }

        private static string TryGetConfigurationSetting(string configName)

        {

            string ret = null;

            try

            {

                ret = RoleEnvironment.GetConfigurationSettingValue(configName);

            }

            catch (RoleEnvironmentException)

            {

                return null;

            }

            return ret;

        }

       private static string TryGetAppSetting(string configName)
        {
            string ret = null;
            try
            {
             ret = System.Configuration.ConfigurationManager.AppSettings[configName];
            }           
            catch (Exception)
            {
                return null;
            }
            return ret;
        }

Method also contains logic to fall back on web.config configuration settings in case it doesn’t exist in serviceconfiguration.cscfg while running on Azure.

The caller is going to retrieve the configuration values using

returnValue = CommonConfigurationManager.PortableConfigurationManager.GetConfigurationValue(txtConfigurationSettingName.Text);

         Configuration values existed at both the places in web.config (under appsetings) and serviceconfiguration.cscfg (under configurationsettings). Above method resolved the appsettings configuration for web.config.

 Now, the interesting part is to manage connection strings. As we know unlike serviceconfiguration.cscfg a change in web.config we have to redeploy the application package while deploying to Windows azure. To address this we added multiple connection strings to web.config file and for selecting the required one we pointed the name of the connection string from serviceconfiguration.cscfg.

Let us first look at the method which is responsible for returning the connection string in PortableConfigurationManager class.

 public static string GetConnectionString(string connectionName)
        {
            string connectionCofigurationName = TryGetConfigurationSetting(connectionName);
            if (string.IsNullOrEmpty(connectionCofigurationName))
            {
                return null;
            }
            else
            {
                return (TryGetConnectionString(connectionCofigurationName));
            }
        }

private static string TryGetConnectionString(string connectionName)
        {
            string ret = null;
            try
            {
                ret = System.Configuration.ConfigurationManager.ConnectionStrings[connectionName].ConnectionString;
            }            
            catch (Exception)
            {
                return null;
            }
            return ret;
        }
 

The public method takes parameter as string which indicates the connection name and the connection name is just a redirection from configuration to point to the connection string name to be used. The redirection is done through web.config for local IIS and serviceconfiguration.cscfg for Windows Azure.

Web.config:

   <connectionStrings>
    <add name="Local"
         connectionString="@Local Connection String"
         providerName="System.Data.SqlClient" />
    <add name="Azure"
        connectionString="@Azure Connection String"
        providerName="System.Data.SqlClient" />
  </connectionStrings>
  <appSettings>    
    <add key ="ConnectionName" value ="Local"/>
  </appSettings>

          ServiceConfiguration.cscfg

  <ConfigurationSettings>
      <Setting name ="ConnectionName" value ="Azure"/>
  </ConfigurationSettings>

You might have understood by now that we are using the configuration ConnectionName to select the appropriate connection string. When the application is running on Local IIS the configuration ConnectionName is going to return value “Local” and the method would return connection string which has name “Local”. Similarly when it is running on Azure it would return connection string which has name “Azure”.

Using this PortableConfigurationManager class and redirection in configuration we could achieve the configuration portability between local IIS and Windows Azure.

Sample code can be downloaded from here

Hope it helps.

Advertisements
  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s