SPWebConfigModification: Persisting Configuration Data in SharePoint 2010

A common requirement in SharePoint 2010 and SharePoint 2007 developments is having somewhere to save your configuration data. Maybe you need to persist a SQL connection string, maybe you need to save the URL of your accounts system web service or perhaps you want to store settings for your web part that in some way alters the behaviour of your application.

SharePoint offers you many ways of doing this, and each has their merits. In this blog posting – the first in a series – we’ll be looking at persisting configuration data using web.config files.

Persistence Using Web.Config

This is a natural choice for ASP.NET developers. We tend to think in terms of config files when it comes to saving settings for our web-based applications.

Web.config files are also perfectly valid places to store this kind of data in SharePoint, but there are some gotchas.

Gotcha #1: When you make a change to a web.config file, it causes the app domain within the ASP.NET application pool to be recycled for that IIS application root. Any others that share the application pool will also get the rug pulled from under them – you’re effectively doing an IISRESET (albeit only on sites in your app pool), which causes an outage for several seconds, and forces ASP.NET to do a recompile next page load.

Gotcha #2: When you add a new web front end server to your SharePoint farm, it will lose settings that were manually keyed into the web.config on other servers. This is because of the Microsoft SharePoint Foundation Web Application service – the service in charge of keeping IIS in sync across your farm – can only restore web.config changes that it knows about.

Microsoft SharePoint Foundation Web Application Service - Services On This Service in Central Administration

Gotcha #3: In a multi-server farm, any changes you make to web.config on one of your web front end servers must be replicated across all web front end servers.

Gotcha #4: If you have extended your Web Application into other Zones, IIS will create multiple sites to host each Zone. Each IIS site will have its own web.config file for you to keep up to date.

So, how do we avoid these problems? Well, we can’t avoid Gotcha #1. It’s how .NET works. Any web.config changes trigger app pool recycling. But we can avoid Gotcha #2, #3 and #4.

The SPWebConfigModification Class

We can automate additions to, and removals from, the web.config file using the SPWebConfigModification class. It’s a SharePoint utility class that allows us to queue up changes to web.config, and then apply them asynchronously at SharePoint’s leisure, across each IIS site for your Web Application, and each server in your farm.

The most important benefit of doing this is that when I add a new server to my farm or otherwise have to restart the Microsoft SharePoint Foundation Web Application service, I’m guaranteed that all my web.config modifications will be applied to the server.

To use the SPWebConfigModification class, you create an instance of it and set the XPath expression to the target node in web.config you’re editing, then the name of the attribute or node to add, and lastly set the value we want to update.

Then it’s a simple matter of passing your SPWebConfigModification object to the Add()method of the WebConfigModifications collection on your target SPWebService (e.g. SPWebService.ContentService).

To write your changes to the batch, invoke Update() on your SPWebService. but note that nothing will happen until you call ApplyWebConfigModifications().

The code bellow shows the steps to add a new appSetting block to your web.config, adding a key called “mySetting” with the value “http://joelblogs.co.uk”:

   1: SPWebService service = SPWebService.ContentService;

   2:  

   3: SPWebConfigModification myModification = new SPWebConfigModification();

   4: myModification.Path = "configuration/appSettings";

   5: myModification.Name = "add [@key='mySetting'] [@value='http://joelblogs.co.uk']";

   6: myModification.Sequence = 0;

   7: myModification.Owner = "AD\JOELJ";

   8: myModification.Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode;

   9: myModification.Value = "<add key='mySetting' value='http://joelblogs.co.uk' />";

  10: service.WebConfigModifications.Add(myModification);

  11:  

  12: /*Call Update and ApplyWebConfigModifications to save changes*/ 

  13: service.Update();

  14: service.ApplyWebConfigModifications();

If you want to read this value later in your code, say for example in a WebPart, then you can use the ConfigurationManager.AppSettings[] collection to access configuration settings in the current web.config.

The code below shows retrieving the value of the “mySetting” key from the appSettings block of your web.config:

   1: string mySetting = ConfigurationManager.AppSettings["mySetting"].ToString();

Advantages

This technique allows you to keep your web.config files in sync, and backed up. Each time SharePoint makes a change to your web.config files, it will create a backup with a time-stamped name in the same folder. It will also ensure that any servers you add, or Zones into which you extend your Web Application, will get the correct web.config entries.

Disadvantages

There are reports that SPWebConfigModification can be flaky. It certainly had issues in SharePoint 2007; use of SPWebModification inside FeatureReceivers is discouraged as sometimes these can go awry. For use elsewhere, make sure the user running the code has administrative permissions to be able to edit the web.config files in the first place.

Links

For more information, have a look at the MSDN article on SPWebConfigModification.

Comments

  1. Nishan says

    Nice article. I am not sure if I agree with “Gotcha #1: When you make a change to a web.config file, it causes the ASP.NET application pool to be recycled for that IIS application root” Recycling appdomain doesn’t necessarily mean recylcling app pool in SharePoint. For example, users don’t get kicked out from a SharePoint site if appdomain is recycled if the site only uses solutions (Dlls) deployed to bin folder (i.e no dlls in bin folder). Would you agree?

  2. Nick says

    Hi Joel,
    I have created a sol with feature even receiver and feature scope as web application.
    all runs good when the solutions Assembly Deployment Target is GAC.
    But when activated the feature for one web application, the web config gets updated on all of the web application.
    when the Assembly Deployment Target is changed to Web application, the system throws error.

    Do you have any reason why I am getting this error.
    Its been long i am struggling with this error. Is it not possible to update only one web application

    Thanks in advance for your help.

  3. Shah says

    Hi Joel,
    I am facing the exact same problem as mentioned by Nick above. I have code to apply web.config setting for single web application, but when someone activates the feature. All the web.config files of all the web applications in SharePoint farm gets updated and as a result the app pool for all the web applications get recycled (even though I did updated for a single web application).
    I just want to know if there is better or correct way of doing this. Where the app pool for the other web applications do not get recycled.

    Nick or Joel, if you guys found any solution, then please share.

    Thanking in advance.

    • Joel Jeffery says

      Hi Shah and Nick,

      My example uses SPWebService.ContentService.WebConfigModifications.Add(). This should make changes to all web.config files of all Web Applications in the Farm. If you want to affect one particular Web Application, you need to use SPWebApplication.WebConfigModifications.Add(), SPWebApplication.Update() and then SPWebApplication.Farm.Services.GetValue().ApplyWebConfigModifications().

      For a more flexible solution, check out the Configuration Manager example on the SharePoint Prescriptive Guidance Pack (http://codeplex.com/spg).

      Hope this helps!

      joel

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>