Friday, August 14, 2009

Change in appSettings restart worker process. How to avoid this restart?

ASP.NET we mostly save application settings in web.config file and these settings are intended for read only. Changing these settings is not always a straight forward way. When some change is made in web.config file ASP.NET starts a new worker process to facilitate incoming requests and discards the old worker process so the old state of the application is lost during this process. To make it clear suppose an application is using sessions as data storage then the data of these sessions will be lost during this restart of the application. This is not a good and acceptable behavior for high traffic web sites.

Luckily ASP.NET 2.0 and later has couple of attributes to avoid this. But remember you still cannot change anything in web.config file directly; it will definitely restart the worker process (w3wp.exe, aspnet_wp.exe). To make this work you must have to place the elements of appSettings, must say, appSettings section in a separate file. This file could be in the form of .txt, .xml or .config. The .config extension is most appropriate as IIS does not allow .config to be browsable by users.

Let’s discuss a scenario, suppose we want to enable logging in our web application and we also want to start and stop this logging by reading a value from web.config file. Our typical web.config file looks like this:

In our sample web application there are two pages, Page1.aspx and Page2.aspx. Pag1 takes input from the user, saves it in session and redirects to Page2. Page2 prints the session value and “Start_Logging” value at screen. Now if we change the value of “Start_Logging” and refresh the page we will see that the session value is lost….hmmm.

Now let’s discuss the steps to avoid this:

1- Add a new item "Web Configuration File" into our project, here I named it Data.config.

2- Delete all the text from the Data.config file except the first line <?xml version="1.0" ?>.

3- Copy the appSettings node from your web.config file and paste in Data.config. Our Data.config will look like this:



4- Delete the elements of the appSettings from the web.config file.

5- Add an attribute "configSource" in appSettings of web.config and provide it the config source. In our case it is the Data.config.

Now the web.config will look like this:



That’s all, we are done. Now we can change the value of “Start_Logging” without the fear of losing our application data. One interesting point is that we can access the appSettings elements in the same way as we normally do and as these are physically stored in the web.config file. Remember one thing if you decide to use "configSource" attribute then you cannot contain any element in your "asppSettings" node of "web.config", if you tried to do this you will get this error message "A section using 'configSource' may contain no other attributes or elements."

In this artilce I used "couple of attributes" words, where or what is the other attribute? The second attribute is "RestartOnExternalChanges". It takes the values true or false and tells whether to restart if exteranl configSource is changed or not. We do not need to mention this attribute in web.config file as in machine.config file the value of this attribute is already set to false. However you can study about this "RestartOnExternalChanges" attribute if you want to restart your application if external file gets change.