Jan 09 2007

Your own configuration setting section in web.config

Posted by admin under ASP.NET 2.0

I have often talked warmly for using appSettings instead of creating your own custom section in web.config - however I do admit there are some pretty nice things with them.

First and maybe most importantly - in a world of component reuse - it is a good way of avoiding name collisions.     

Secondly - it brings structure to your project(s).

It also eases deployment and integration of the components in new applications.

On the other hand - my main objection to custom sections has been it's too hard to develop them. You first try find the old project of where you know you have used it - and then you copy the code to the new project, you write your new CustomSpecialSettings class - and last you try to write the System.Configuration.IConfigurationSectionHandler.Create function =  XML parsing to fill the CustomSpecialSettings object.

The last part is never fun - at least it isn't for me. So - I often take the easy way out and just use <appSettings> instead - creating unique named keys like "CustomSpecialSettings_Foo" and "CustomSpecialSettings_Bar" etc.

However I just (yes, I am slow...) found two great articles (check the links section) on how to make the parsing automatic - and to accomplish that it uses XML serialization. That's a great idea! It allows for just writing the settings class, perhaps tag it with some xml attributes to make it deserialize correctly.

 I havn't created a downloadable solution for this, the mentioned articles already does - I am however currently working on a pretty useful server control (to be freely released) where I am gonna use the technique.

I will however descrive how I use it - and also give you an advice - which "ciosted" me the better part of this morning.

I have created a dll - XmlConfiguration, just containing the XmlConfiguration class:



using System;
using System.Xml;
using System.Xml.Serialization;
using System.Xml.XPath;
/*
 Code by Jeff Gonzales - http://www.15seconds.com/issue/040504.htm
 * 
 * just put into own dll by Stefan Holmberg http://www.aspcode.net
 
 */
namespace XmlConfigurator
{
    public sealed class XmlConfigurator : System.Configuration.IConfigurationSectionHandler
    {
        #region Private member variables
        #endregion

        #region Constructors, destructors and initializers

        public XmlConfigurator()
        {
        }

        #endregion

        #region Private methods
        #endregion

        #region Protected methods
        #endregion

        #region Public methods

        public object Create(object parent, object configContext, System.Xml.XmlNode section)
        {
            Object settings = null;

            if (section == null) { return settings; }

            XPathNavigator navigator = section.CreateNavigator();
            String typeName = (string)navigator.Evaluate("string(@type)");
            Type sectionType = Type.GetType(typeName);

            XmlSerializer xs = new XmlSerializer(sectionType);
            XmlNodeReader reader = new XmlNodeReader(section);

            try
            {
                settings = xs.Deserialize(reader);
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex.Message);
            }
            finally
            {
                xs = null;
            }

            return settings;

        }


        #endregion

        #region Public properties
        #endregion

        #region Private Enums
        #endregion

        #region Public Enums
        #endregion
    }
}



Now my web.config looks like this:



<configuration>
  <configSections>
    <section name="ASPCodeHeaderManagerSettings" type="XmlConfigurator.XmlConfigurator, XmlConfigurator" />
  </configSections>
  <ASPCodeHeaderManagerSettings type="ASPCodeHeaderManager.ASPCodeHeaderManagerSettings, ASPCodeHeaderManager">
    <ScriptsInHeaderCompression>1</ScriptsInHeaderCompression>
    <IncludeScriptsCompression>2</IncludeScriptsCompression>
    <HandlerUrl>aspcodescripts/getjs.ashx</HandlerUrl>
  </ASPCodeHeaderManagerSettings>



In the dll ASPCodeHeaderManager I define the class ASPCodeHeaderManager like this:



using System;
using System.Xml.Serialization;

namespace ASPCodeHeaderManager
{
    [Serializable]
    public class ASPCodeHeaderManagerSettings
    {
        public ASPCodeHeaderManagerSettings()
        {
        }
        private string m_strHandlerUrl = ""; // ""

        public string HandlerUrl
        {
            get { return m_strHandlerUrl; }
            set { m_strHandlerUrl = value; }
        }

        private string m_nScriptsInHeaderCompression = "1"; //default - endast wehitespace

        public string ScriptsInHeaderCompression
        {
            get { return m_nScriptsInHeaderCompression; }
            set { m_nScriptsInHeaderCompression = value; }
        }
        private string m_nIncludeScriptsCompression = "1"; //default - endast wehitespace

        public string IncludeScriptsCompression
        {
            get { return m_nIncludeScriptsCompression; }
            set { m_nIncludeScriptsCompression = value; }
        }

    }
}

The important thing is to use the same name everywhere:

<section name="ASPCodeHeaderManagerSettings"

<ASPCodeHeaderManagerSettings type='''

public class ASPCodeHeaderManagerSettings

Cause first I tried to use a clas name of just Settings - however the serialization didn't work then - the class name and xml tag name must match! I thought that deserialize would serialize the InnerContent of the <ASPCodeHeaderManagerSettings> tag (which just contains the properties so to speak) - however after scratching my head for some hours I finally understood what was going on.

 

 

Links