Daniel Auger
Daniel Auger

Reputation: 12621

Is there an event to handle/method to override that takes place before the Web.config is parsed/checked for changes?

I'm wondering if there is an event that can be handled or a method that can be overridden that takes place before the Web.config file is parsed and monitored by the asp.net 3.5 application / AppDomain lifecycle.

The practical reason for this is that I'd like to be able to write the Web.config file from a copy in the database while the application is starting up depending on the deployment environment. The reason for this is because we have a manual application deployment process and a web farm. Web.config changes often fall through the cracks or fail to be propagated to all servers on the web farm because of the manual process. Unfortunately we are going to be staying with a manual deployment process for the foreseeable future. This being the case, it would be great if there was a way for an app to go grab its web config on first startup. If I could get that working, the next logical thing to do would be to create a SQL dependency/notification to cause an AppDomain unload whenever the config file is changed in the databases so new changes would be pulled and written.

So far the only way I've figured out how to manage this is to do something like the below psuedocode that has the unfortunate side effect of causing two application load cycles per attempted start. Additionally, I'm pretty sure the first request that comes in if the app is idle will go up in smoke due to the restart.

// PSEUDOCODE
// In global.asax.cx
protected void Application_Start(object sender, EventArgs e)
{
   bool loadConfigFileFromDB = GetConfigLoadOptionFromLoadOptionsConfigFile();
   string webConfigPath = GetWebConfigPath();

   if (loadConfigFileFromDB)  // Most likely false in development so debugging works
   {                          // with a local web.config

      if (File.Exists(webConfigPath))  // We are not starting up for the first time 
      {                                // since app was deployed
         if (File.GetCreationTime(webConfigPath) < DateTime.Now.AddMinutes(-1))
         {
            // Web config is more than a minute old, so chances are we
            // aren't in an app restart after writing the config.
            WriteWebConfigFromDatabase(); // This will cause a restart.
         }

         // else, web.config was probably just written and we are in a 
         // restart after writing the config. In this case, let the application continue on
      }
      else // First time starting up, so it's safe to assume we can write
      {    // the config and restart.
         WriteWebConfigFromDatabase(); // This will cause a restart.
      } 
   }            
}

Obviously a build or deployment task would be the best way handle replacing the Web.config per environment, but unfortunately I am not in a situation where that can happen.

EDIT

The intent of this is not to have dynamic settings while the app is running, it is to help manage differing Web.config files per environment (Stage/QA/Production). Example, in a separate non-Web.config file we'd have an environment setting. After deployment when the app fired up, it would use the settings in this file (the environment and the connection string) to go pull and write the web config for that environment. The settings would not be dynamic after application startup.

Upvotes: 2

Views: 269

Answers (3)

Daniel Auger
Daniel Auger

Reputation: 12621

I'm wondering if there is an event that can be handled or a method that can be overridden that takes place before the Web.config file is parsed and monitored by the asp.net 3.5 application / AppDomain lifecycle.

After doing a few days of research I'm going to say the answer to this question is: No, there is no such event that can be handled or method that can be overidden. If someone ever comes along and can show otherwise, I will deselect this as the answer to the question.

Upvotes: 0

Dmytrii Nagirniak
Dmytrii Nagirniak

Reputation: 24108

You are doing weird thing.

UPDATE (also removed unrelated text):
Ok. So you need to automatically propagte new version of the application to all servers. I do not see a reason to do it from application itself. Instead it should be another utility/batch/installer that does this kind of stuff. I believe ASP.NET application deploying itself will hit a lot of issues (what if you will need to deploy assemblies along with web.config)?

I think simple batch-xcopy approach will do the job for you:

  1. Create a .bat file that accepts 1 parameter:Envoronment=[Stage/QA/Production].
  2. Copy all the required files to a separate temporary directory (so you can modify things without touching the original code).
  3. Modify web.config and other things you need (you can use some utility for that) as per Environment parameter.
  4. XCOPY all files to all required servers as per Environment parameter.

There is no need to incorporate the deployment process into the application itself.
For Windows applications it is ok as you can use bootstrapper, but not for ASP.NET.

Upvotes: 2

Sam
Sam

Reputation: 6265

Application_End is the closest event - it fires just prior to the unloading of the AppDomain for the web application. You could just update the Web.config file there.

In principle it should work - the AppDomain is unloaded, so the config has to be reloaded when the AppDomain starts up again, by which time the latest config would already exist on disk.

Also, I'm assuming that ASP.NET stops monitoring the Web.config for further changes, as it has already decided to shut down the application - my only concern is that writing the file again would cause an infinite loop to occur.

It can't hurt to try. It is a weird thing to do though. It would be good to have some more background on why you are needing to do this in the first place.

Upvotes: 0

Related Questions