Making SharePoint's web.config changes manageable

Posted on 12/30/2008 @ 3:28 PM in #SharePoint by | Feedback | 6090 views

Here is one of the biggest problems with SharePoint - it's largely broken web.config management prowess. I won't actually document every single issue here, because my good friend Reza has done a fantastic job at pointing those out. But, in a large SharePoint project involving lots of custom code, one of the most common changes you'd need to do is .. APPSETTINGS!

Yep, it's that pesky <appSettings/> node in your web.config where everyone and their daughters will want to store configuration information such as connectionstrings, wcf endpoint addresses, etc. Now, some people say .. ahh you should store all that config information in a list.

I say, are you kidding me!? No seriously! Why? A list can be changed through the UI, or well, even accessed through the UI. While a blinded by faith SharePoint fanatic will say .. it makes it more manageable, a more practical person will say, there is a reason why these settings live on a server file that will never get rendered through IIS on a browser. An end-user, non-deploy person should never be able to change such settings. For serious, you don't want internal server names etc. to be shown over the UI .. in any case. Not to mention, you have to protect that list, break security inheritance, impersonate to read, ugh! never mind!

So, here is a much better way.

a) Ue SPWebconfigModification to make the following entry.

<appSettings file="appSettings.Config"/>

b) Create a new solution, which deploys a file called "appSettings.Config" in the web root. This can be very easily done using WSPBuilder where you simply place a 80 directory in your solution, and throw the appSettings.Config in there. This will reliably deploy the appSettings.config to all the web front ends on the given web app.

c) Create an appSettings.Config file as follows -

   1:  <?xml version="1.0"?>
   2:  <appSettings>
   3:    <add key="kutta" value="kamina"/>
   4:  </appSettings>

d) Use it in your code in the usual fashion -->

   1:  Response.Write(ConfigurationManager.AppSettings["kutta"]);

This is much better than dealing with the intricacies/idiosyncracies of SPWebConfigModification

Sound off but keep it civil:

Older comments..


On 12/30/2008 11:08:50 PM Jonas said ..
I consider this a worst practice just beacuse of what you are trying to "fight".

1) How are you going to keep your web.config files in synch across all WFE's, a new WFE is added?

2) Then how are you going to keep all your external app config files in synch? Manually? Or are you going to write a custom timer job framework to do it?

No just stay out of web.config if at all possible, some things has to go there but for ANY other configuration let the platform store it.

1) Persisted ptoperties on SPFarm - SPSite - SPWeb choose appropriate scope.

You don't have to use a list but for some things it's a perfect fit.

And now you got your backup/restore story covered too.

Thanks


-Jonas


On 12/31/2008 12:25:14 AM Sahil Malik said ..
Jonas,

As suggested, if you deployed the appExternal.Config as a part of solution, it will be automatically replicated across WFEs and newer WFEs will automatically get it as a part of a solution package. There is no manual intervention required. There will also be no synch issues. No timer jobs will be necessary.

Now regarding property bags, SPSite has no property bag on it. I guess you could store stuff at RootWeb.Properties, but there is no guarantee that RootWeb will always remain RootWeb. Properties is the second best option.

S


On 12/31/2008 5:19:13 AM Robert Seso said ..
Hi Sahil,

on my last project I decided to store all my app settings in the Config DB. Doing that is easy, you only have to create a class that inherits from SPPersistedObject and create your settings as fields marked with the Microsoft.SharePoint.Administration.Persisted attribute. There are many advantages to this:

* all changes are immediately visible across the entire farm

* you are free to name your settings any way you want without the danger that the name had already been used by someone else (which can happen when multiple custom solutions are installed on the same farm, especially if they come from different sources and evryone thought "kutta" was a cool name for a setting...)

* you get a strongly typed class to access your settings

* all settings are automatically backed up together with the config DB

The only drawback is that you must build a custom UI to edit the settings. We created a web part for that, but one can make a standalone web or win app if exposing this through SharePoint is an issue. One COULD probably also edit the settings manually by changing the XML in the "Properties" field of the "Objects" table in the Config DB, I haven't tried though. You can retrieve the settings issuing SELECT Properties FROM Objects WHERE [Name] = 'your configuration name' against the config DB.

Regards, Robert


On 12/31/2008 9:14:26 AM Sahil Malik said ..
Robert,

Now that sounds like a very interesting approach.

S


On 12/31/2008 10:43:37 AM Ryan Miller said ..
I'm with you Sahil. The web.config is the way to go for these and the new WSS framework makes it so easy to use. I just don't like the idea of the performance overhead associated with using a list.

Though these manipulations aren't hard to do in your feature receivers, I encapsulated the monotonous code in a solution and threw it out on codeplex.


WebConfigManager: http://www.codeplex.com/MyLocalBroadband/Wiki/View.aspx?title=Web%20Config%20Manager

Example Usage: http://www.codeplex.com/MyLocalBroadband/SourceControl/changeset/view/19074#365071

The one drawback I've come across with the web.config (that a list won't fix either) is that if you have an internal web app extended to an external web app, there are times where you want different configuration information in them. For me, this has meant little more than a few extra, unused, keys in one file or another, but I could see it being a real issue in some situations.


On 12/31/2008 10:53:02 AM Tom Resing said ..
Sahil, I think you present an intersting option here with the appSettings.config file. SPPersistedObject is interesting too, Modifying the Config DB is never a good idea, but it's usable without that. -Tom


On 1/21/2009 10:19:54 PM Jag said ..
Kutta, Kamina - what a way to name for a key setting? Hopefully lot of your readers don't know what they mean..lol


On 2/17/2009 4:25:20 AM Alex Angas said ..
Hi Sahil,

Interesting viewpoint. Personally I find keeping my config values in a list much more practical than fiddling around with web.config! I don't have a problem with setting the list to break inheritance and be admin only.

However, the next time I need to store config I'm going to check out SPConfigStore by Chris O'Brien: http://www.codeplex.com/SPConfigStore/. I believe this uses SPPersistedObject like other people in the comments have been saying and it seems to have some good features for more complex config structures.

Cheers, Alex.