Click here to Skip to main content
Click here to Skip to main content

Tagged as

Go to top

A useful custom configuration section for inline unconstrained XML

, 20 Aug 2012
Rate this:
Please Sign up or sign in to vote.
As I was writing a small TCP server for serving a Silverlight local TCP policy, I came across a certain need. Inspired by Dan Wahlin’s server implementation, I chose to write a simplified version for myself. I needed to keep …Read more »

As I was writing a small TCP server for serving a Silverlight local TCP policy, I came across a certain need. Inspired by Dan Wahlin’s server implementation, I chose to write a simplified version for myself. I needed to keep some XML in the App.config without constraining it with a schema.

The normal solution in this case is a custom section, sibling to appSettings if you wish. So my App.Config looked at first like this:

<configuration>
  <appSettings>
    <add key="ipAddress" value="127.0.0.1"/>
  </appSettings>
  <access-policy>
    <cross-domain-access>
      <policy>
        <allow-from>
          <domain uri="*" />
        </allow-from>
        <grant-to>
          <socket-resource port="4502" protocol="tcp" />
        </grant-to>
      </policy>
    </cross-domain-access>
  </access-policy>
</configuration>

Upon running the program, even addressing the “ipAddress” key in the appSettings section throws an exception like:

System.Configuration.ConfigurationErrorsException was unhandled
  Message="Configuration system failed to initialize"
  Source="System.Configuration"
  BareMessage="Configuration system failed to initialize"
  Line=0
  StackTrace:
       at System.Configuration.ConfigurationManager.PrepareConfigSystem()
       at System.Configuration.ConfigurationManager.GetSection(String sectionName)
       at System.Configuration.ConfigurationManager.get_AppSettings()
       at ConsoleApplication1.Program.Main(String[] args) in C:\Users\Andrei\Documents\
            Visual Studio 2008\Projects\ConsoleApplication1\ConsoleApplication1\Program.cs:line 21
       at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
       at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException: System.Configuration.ConfigurationErrorsException
       Message="Unrecognized configuration section access-policy.
               (C:\\Users\\Andrei\\Documents\\Visual Studio 2008\\Projects\\
                ConsoleApplication1\\ConsoleApplication1\\bin\\Debug\\
                ConsoleApplication1.vshost.exe.config line 8)"
       Source="System.Configuration"
       BareMessage="Unrecognized configuration section access-policy."
       Filename="C:\\Users\\Andrei\\Documents\\Visual Studio 2008\\Projects\\
         ConsoleApplication1\\ConsoleApplication1\\bin\\Debug\\ConsoleApplication1.vshost.exe.config"
       Line=8
       StackTrace:
            at System.Configuration.ConfigurationSchemaErrors.ThrowIfErrors(Boolean ignoreLocal)
            at System.Configuration.BaseConfigurationRecord.ThrowIfParseErrors(ConfigurationSchemaErrors schemaErrors)
            at System.Configuration.BaseConfigurationRecord.ThrowIfInitErrors()
            at System.Configuration.ClientConfigurationSystem.EnsureInit(String configKey)
       InnerException:

So something is wrong. We need to tell the runtime that the “access-policy” section is allowed.

<configuration>
  <strong>
   <configSections>
    <section name="access-policy" type="CustomSections.InlineXmlSection, CustomSections"/>
   </configSections>
  </strong>
  ...

At first, I didn’t place the type attribute in the “section” element, but it turned out it had to be specified and not be empty. Moreover, it must contain the fully-qualified class name and the assembly which contains it. The class must inherit from System.Configuration.ConfigurationSection.

So, I created an assembly called CustomSections, and added references to the System.Configuration assembly and the System.Xml assembly.

All you need to do is override the DeserializeSection method and load the XML document in there:

using System.Configuration;
using System.Xml;

namespace CustomSections
{
  public class InlineXmlSection : ConfigurationSection
  {
    public XmlDocument Content { get; private set; }

    protected override void DeserializeSection(XmlReader reader)
    {
      (this.Content = new XmlDocument()).Load(reader);
    }
  }
}

The code is pretty self-explanatory: we instantiate a new XmlDocument and load it from the XmlReader provided to us by the configuration infrastructure. If anything goes bad, the exception handling will be the responsibility of the caller. In this case, the first call to ConfigurationManager.

Now, let’s put the code to use:

private static void Main(string[] args)
{
  expectedRequestBytes = Encoding.UTF8.GetBytes("<policy-file-request/>");
  listener = new TcpListener(IPAddress.Parse(ConfigurationManager.AppSettings["ipAddress"]), 943);
  var policySection = (InlineXmlSection)ConfigurationManager.GetSection("access-policy");
  policyBytes = Encoding.UTF8.GetBytes(policySection.Content.OuterXml);
  ...
}

The underlined code is the relevant portion (the rest is provided for context). We get the section via ConfigurationManager.GetSection, and we have to cast the result to the desired section type. Then we use the section as we see fit.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Andrei Ion Rînea
Software Developer (Senior) IBM, Business Analytics
Romania Romania
No Biography provided

Comments and Discussions

 
-- There are no messages in this forum --
| Advertise | Privacy | Mobile
Web01 | 2.8.140926.1 | Last Updated 20 Aug 2012
Article Copyright 2012 by Andrei Ion Rînea
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid