18

Suppose I have a Custom Config File which corresponds to a Custom-defined ConfigurationSection and Config elements. These config classes are stored in a library.

Config File looks like this

<?xml version="1.0" encoding="utf-8" ?>
<Schoool Name="RT">
  <Student></Student>
</Schoool>

How can I programmatically load and use this config file from Code?

I don't want to use raw XML handling, but leverage the config classes already defined.

1
  • 3
    why dont u choose selected answer? Commented Nov 13, 2012 at 13:33

4 Answers 4

17

You'll have to adapt it for your requirements, but here's the code I use in one of my projects to do just that:

var fileMap = new ConfigurationFileMap("pathtoconfigfile");
var configuration = ConfigurationManager.OpenMappedMachineConfiguration(fileMap);
var sectionGroup = configuration.GetSectionGroup("applicationSettings"); // This is the section group name, change to your needs
var section = (ClientSettingsSection)sectionGroup.Sections.Get("MyTarget.Namespace.Properties.Settings"); // This is the section name, change to your needs
var setting = section.Settings.Get("SettingName"); // This is the setting name, change to your needs
return setting.Value.ValueXml.InnerText;

Note that I'm reading a valid .net config file. I'm using this code to read the config file of an EXE from a DLL. I'm not sure if this works with the example config file you gave in your question, but it should be a good start.

Sign up to request clarification or add additional context in comments.

Comments

8

Check out Jon Rista's three-part series on .NET 2.0 configuration up on CodeProject.

Highly recommended, well written and extremely helpful!

You can't really load any XML fragment - what you can load is a complete, separate config file that looks and feels like app.config.

If you want to create and design your own custom configuration sections, you should definitely also check out the Configuration Section Designer on CodePlex - a Visual Studio addin that allows you to visually design the config sections and have all the necessary plumbing code generated for you.

2 Comments

This is helpful but not an answer to the question. I read all three articles and I'm still none the wiser.
@Andrew Myhre: I was trying to say: instead of rolling your own and re-inventing the wheel - use what's already available in the .NET framework. Stop re-inventing the wheel! There are plenty enough wheels out there already - use them!
2

The configSource attribute allows you to move any configuration element into a seperate file. In your main app.config you would do something like this:

<configuration>
  <configSections>
    <add name="schools" type="..." />
  </configSections>

  <schools configSource="schools.config />
</configuration>

3 Comments

True - but even in this case, you need to create your own custom configuration element for the <configSections> definition part.
@marc_s: as I read the OP, the author already has a "Custom-defined ConfigurationSection", but is unsure how to make utilize this as a "Custom Config File". I might be wrong though.
You could be right :-) Guess I didn't read the question carefully enough - mea culpa.
2

Following code will allow you to load content from XML into objects. Depending on source, app.config or another file, use appropriate loader.

using System.Collections.Generic;
using System.Xml.Serialization;
using System.Configuration;
using System.IO;
using System.Xml;

class Program
{
    static void Main(string[] args)
    {
        var section = SectionSchool.Load();
        var file = FileSchool.Load("School.xml");
    }
}

File loader:

public class FileSchool
{
    public static School Load(string path)
    {
        var encoding = System.Text.Encoding.UTF8;
        var serializer = new XmlSerializer(typeof(School));

        using (var stream = new StreamReader(path, encoding, false))
        {
            using (var reader = new XmlTextReader(stream))
            {
                return serializer.Deserialize(reader) as School;
            }
        }
    }
}

Section loader:

public class SectionSchool : ConfigurationSection
{
    public School Content { get; set; }

    protected override void DeserializeElement(XmlReader reader, bool serializeCollectionKey)
    {
        var serializer = new XmlSerializer(typeof(School)); // works in     4.0
        // var serializer = new XmlSerializer(type, null, null, null, null); // works in 4.5.1
        Content = (Schoool)serializer.Deserialize(reader);
    }
    public static School Load()
    {
        // refresh section to make sure that it will load
        ConfigurationManager.RefreshSection("School");
        // will work only first time if not refreshed
        var section = ConfigurationManager.GetSection("School") as SectionSchool;

        if (section == null)
            return null;

        return section.Content;
    }
}

Data definition:

[XmlRoot("School")]
public class School
{
    [XmlAttribute("Name")]
    public string Name { get; set; }

    [XmlElement("Student")]
    public List<Student> Students { get; set; }
}

[XmlRoot("Student")]
public class Student
{
    [XmlAttribute("Index")]
    public int Index { get; set; }
}

Content of 'app.config'

<?xml version="1.0"?>
<configuration>

  <configSections>
    <section name="School" type="SectionSchool, ConsoleApplication1"/>
  </configSections>

  <startup> 
      <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
  </startup>

  <School Name="RT">
    <Student Index="1"></Student>
    <Student />
    <Student />
    <Student />
    <Student Index="2"/>
    <Student />
    <Student />
    <Student Index="3"/>
    <Student Index="4"/>
  </School>

</configuration>

Content of XML file:

<?xml version="1.0" encoding="utf-8" ?>
<School Name="RT">
  <Student Index="1"></Student>
  <Student />
  <Student />
  <Student />
  <Student Index="2"/>
  <Student />
  <Student />
  <Student Index="3"/>
  <Student Index="4"/>
</School>

posted code has been checked in Visual Studio 2010 (.Net 4.0). It will work in .Net 4.5.1 if you change construction of seriliazer from

new XmlSerializer(typeof(School))

to

new XmlSerializer(typeof(School), null, null, null, null);

If provided sample is started outside debugger then it will work with simplest constructor, however if started from VS2013 IDE with debugging, then change in constructor will be needed or else FileNotFoundException will occurr (at least that was in my case).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.