Tuesday, June 23, 2009

Reading from a configuration file in .NET.

Recently I was working on a web application which had an exe added as a reference to the project. The exe had its own App.Config file where some setting related to the application was saved and these were read using the code below. Pretty straight forward code.

private static string userName = ConfigurationSettings.AppSettings["UserName"].ToString();
private static string userEmail = ConfigurationSettings.AppSettings["UserEmail"].ToString();

In the above code we are trying to retrieve value from the AppSettings section of the App.Config file of the application using the ConfigurationSettings class’ AppSettings property which is a namevalue collection object. The above approach is a deprecated method. Instead of the above approach, one can make use of the below code to retrieve the appsettings values.

private static string userName = ConfigurationManager.AppSettings["UserName"].ToString();
private static string userEmail = ConfigurationManager.AppSettings["UserEmail"].ToString();

ConfigurationSettings API has become obsolete and has been replaced with the ConfigurationManager class to read the configuration  setting of an applicatioin. To read the application settings or AppSettings of an application one can make use of ConfigurationManager.AppSettings. But my problem was not related to the API becoming obsolete. The system was throwing error when the system was trying to read the configuration. The errors are pasted below.

The parameter 'exePath' is invalid.
Parameter name: exePath

An error occurred loading a configuration file: The parameter 'exePath' is invalid.
Parameter name: exePath

Object reference not set to an instance of an object.

The reason why these errors were thrown is that while we were trying to read the keys from the configuration file the key were actually not present  in the “AppSettings” section.

As I said earlier the exe file was added as a reference in an ASP.NET web application and due to some reason when the exe code was accessed through the ASP.NET web application it was throwing error. The same exe application when executed independently was running without any exceptions.

On debugging it was found that, as the request was coming from the ASP.NET web application to the exe file the ConfigurationManager’ AppSettings property had values from the appSettings section of web.config file of the web application. But I wanted the appSettings values of the App.Config file of the exe application. The only solution to my problem was to read from the app.config file of the exe file. Below is the code to read from the configuration file.

string filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, “Bin”);
/*If checking to check whether the bin folder exists. As this is a console application the exe can be copied to any place and can be executed. If that is the case there will be no bin folder. */
if (!Directory.Exists(filePath))
{
    filePath = AppDomain.CurrentDomain.BaseDirectory;
}
/*As the request for this class can come from both exe and website we need to combine the paths. We are first retrieving the path using the AppDomain' BaseDirectory propety and then retrieving the exe name alone. Finally passing the combined file path to ConfigurationManager class. */
filePath = Path.Combine(filePath, Path.GetFileName(System.Reflection.Assembly.
GetExecutingAssembly().Location));
System.Configuration.Configuration theConfig = ConfigurationManager.
OpenExeConfiguration(filePath);

KeyValueConfigurationCollection configuration = theConfig.AppSettings.Settings;
userName = configuration["UserName"] == null ? string.Empty :
configuration["UserName"].Value;
userEmail = configuration["UserEmail"] == null ? string.Empty :
configuration["UserEmail"].Value;

In the above code I am using AppDomain class to retrieve the directory from where the application is executing itself. This approach was taken because the exe will run on its own or can be copied and pasted anywhere and it can run from there or as in my case the request can come from an ASP.NET application. If the exe is added as a reference in an ASP.NET web application, the exe will be copied to the bin folder of the ASP.NET application. So you can see there is a checking to see if there is a “Bin” folder, if there is one the app.config settings will be read from there else it will read from the base directory.

Once the file path along with the exe file name is properly formed we are using ConfigurationManager’ OpenExeConfiguration method to open the configuration file of the exe file. One thing to note here is that we are using “GetExecutingAssembly().Location” property and retrieving the file name and passing the application name along with the extension (.exe) to the OpenExeConfiguraiton method. There is no need to specify “app.config” file name. The reason is whenever an exe is successfully compiled it will create a config file with the same name with a .config extension. For e.g. if you have an exe named “one.exe”, if it is successfully compiled it will create a config file with “one.exe.config” as the name.

Once the config file is successfully opened using “OpenExeConfiguration” method it returns a Configuration object. After successfully retrieving the configuration object, in the next line we are getting the application’ settings using the “AppSettings.Settings” property. The “Settings” property returns a “KeyValueConfigurationCollection” object. Using KeyValueConfigurationCollection object one can read the values of the configuration file. In the above code we are using “configuration["UserName"]” to read the value stored against the “UserName” key. Here the “UserName” is the key. So that’ about reading configuration settings from a configuration file of an application.

Try to know more.

Sandeep

10 comments:

  1. You are a genius! I found your post after wasting almost two hours looking for a way to load the my xxx.dll.config from the Website\bin folder! Thanks a lot!

    ReplyDelete
  2. Thanks man. I am happy that my blog helped you to find solution for your problem.

    ReplyDelete
  3. Hi Sandeep
    Nice explanation. can you help me out in reading a config file which is not in the app location. Say for example c:\\allconfigs\\myconfig.config

    ReplyDelete
  4. This is great! I ran into a very similar situation.

    ReplyDelete
  5. Dude... you just saved me a crapload of time. THanks a lot for the blog post.

    ReplyDelete
  6. I'm sorry but your solution is completely wrong; the config file reads absolutely nothing.

    ReplyDelete
  7. Hi there,
    I would appreciate if you could elaborate what problem you are facing. This will help me correct any errors in the pasted code. All the codes provided here have been thoroughly tested and they were working. Also there are others who are saying the blog post is working and has helped them. So, as long you don't let me know where the problem is I will assume it is working.

    ReplyDelete
  8. Now two years later, this post is still helping! I found this and helped me resolve my headache. Although, I only used this to get the Configuration object so that I could do my own thing with Configuration.GetSection and pull the properties into a class. This worked for me for publishing web application with its own web.config making reference to my custom.dll and now its own custom.dll.config. Note: I had to remember to to set the "Copy to Outup Directory" property on the dll!

    Thanks,
    Nick F.

    ReplyDelete
  9. Excellent article. Thanks.

    ReplyDelete

Please provide your valuable comments.