Welcome to MSDN Blogs Sign in | Join | Help

saurabhd's musings

Saurabh Dasgupta works for Microsoft Consulting Services. - '640kb ought to be enough for anybody'
An approach towards centralized web.config management in WSS/MOSS

Introduction

Let me be very frank with you. I love WSS 30/MOSS technologies. Building a portal for sharing information and collaborating has been made so simple with WSS/MOSS. The architects of WSS/MOSS rightly chose to build over the foundations provided by ASP.NET. Like any ASP.NET application, the web.config file plays a very important role in WSS/MOSS in carrying out low level technical customizations. WSS/MOSS web.config files can be humungous. Try as much I can, I invariably need more than an attempt to get my web.config modifications right. The problem becomes even more significant if I am working on a load balanced SharePoint farm comprising of more than one Web Front End server. The sheer size and complexity of a WSS/MOSS web.config and the likelihood of making inadvertent modification were the key drivers for this post. In this post, I have described an approach to simplify the task of modifying web.config files in a WSS/MOSS farm and keeping all the web.config files in sync in a multi-WFE farm.

Typical web.config file

The web.config file for a MOSS/WSS application has a section group by the name of 'Sharepoint'. This group has several sections defined within. Some of these sections are listed below:

  1. SafeControls
  2. RuntimeFilter
  3. WebPartLimits
  4. WebPartCache
  5. WebPartWorkItem
  6. WebPartControls
  7. SafeMode
  8. MergedActions
  9. PeoplePickerWildcards

Out of the above, I find myself dealing with SafeControls very often. Therefore, I shall restrict my discussion to the centralized management of entries under SafeControls section.

Approaches to Centralized Management of web.config

Based on discussions with my colleagues, I have listed down some of the possible approaches that would help in simplifying the management of web.config files on a more 'central' basis.

  1. Install customizations in the \12\CONFIG directory as specified in the WSS SDK 
  2. Use the SPWebConfigModification class. As implemented in the SharePointDebugger solution.
  3. Do nothing! Manipulate the web.config file directly as a XML file.

Using section handlers for converting configuration XML into custom objects

A section handler in ASP.NET 20 is a custom assembly that is used to handle the contents of a particular section. WSS/MOSS rely on section handlers to provide 'getters' for the web.config, rather than reading the files through XML DOM library. A section is a custom XML hive in the application configuration file for storing application specific information.

  1. All sections are registered under the <configSections> node of the web configuration file
  2. A section must have a class associated with it. This information is provided by the Type attribute
  3. image
  4. The class must implement interface IConfigurationSectionHandler
  5. A typical section would resemble:
  6. image
  7. The interface IConfigurationSectionHandler has a method object Create(object parent, object configContext, XmlNode section); The parameter 'section' represents a XML fragment shown above
  8. The method Create is expected to return a meaningful custom object which would be useful for accessing the XML information. In most cases the implementation of your Create method would end up returning a collection of custom objects.

Making a configuration file read information from a SQL Database

Out of box Section handler for SafeControls section

The SafeControls section has a registered handler which is of the type Microsoft.SharePoint.ApplicationRuntime.SafeControlsConfigurationHandler. This class cannot be inherited because it is marked 'sealed'. As discussed above, the type SafeControlsConfigurationHandler implements the interface System.Configuration.IConfigurationSectionHandler. In the following sections I have described an approach to create a wrapper section handler which would read a list of SafeControls information from a SQL database and pass it on to the Create method of SafeControlsConfigurationHandler, thereby fooling the latter class about the source of the configuration information.

A custom section handler for SafeControls

  1. Let us design a relational table called tblSafeControls. This table would have replicate the attributes found in the <SafeControl> element through relational columns. There would be columns for Assembly, Namespace, Typename, Safe and AllowRemoteDesigner
  2. image
  3. Let us add a connection string information to the <SafeControls> element as shown below
  4. image
  5. Let us create a class MySafeControlsConfigurationHandler and implement the interface IConfigurationSectionHandler.
  6. Provide a body for the method public object Create(object parent, object configContext, XmlNode section);
  7. What next? If you observe, one of the inputs to this method is an object of XmlNode. This is the information contained in the web.config file in XML format.
  8. The pseudo code for the Create( object parent, object configContext, XmlNode section) is
    1. Read the connectionStringName attribute from the 'section' DOM parameter
    2. Obtain the connection string represented by connectionStringName from the <connectionStrings> section
    3. Establish a connection to the database and read the list of  safe controls from the table tblSafeControls.
    4. Create a clone of the XML node 'section', name this 'section_clone'
    5. Manipulate the XML DOM for 'clone_section' by adding new <SafeControl/> elements , thereby populating the in-memory XML DOM with information from the central database. 
    6. In the last step, create an instance of SafeControlsConfigurationHandler class and invoke the Create method by passing the section_clone XML node
    7. The return Object obtained from Create should be returned back to the caller
  9. image 

Conclusion

To deploy the above system , the following one time activities need to be carried out. After this, all additions to the <safecontrols> should happen at the database tables

    1. The web.config for all the WFEs need to be modified by adding the connection string  information.
    2. The custom handler assembly should be added to the GAC on all the WFEs.I am not sure if this has been delved with before.

This approach would require further engineering refinement. E.g. Caching of information to avoid making repeated trips to the central configuration database. I would be delighted to hear your thoughts on this idea, your responses may give me the spark to take this work to a finished solution.

Disclaimer

These ideas expressed here are solely those of the author and not necessarily shared by Microsoft

Posted: Saturday, December 13, 2008 1:26 AM by Saurabh Dasgupta

Comments

Peter said:

Is there a reason you're manually editing SafeControls versus using the Solution framework to edit them for you?

I would say as advice, try out packaging your web parts with WSPBuilder, and once you see how easy and automatic SafeControl additions are, you'll abandon this whole idea.

# December 15, 2008 12:13 PM

saurabhd said:

Packaging the web parts using the Solution Framework would definitely work. The approach that I have presented here is insipired by a greater need for centralizing web.config information, in cases where configuration data becomes too large to be handled by effectively a flat file.

# December 15, 2008 4:32 PM
Leave a Comment

(required) 

(required) 

(optional)

(required) 

  
Enter Code Here: Required

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Page view tracker