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.
C
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).
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>
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.
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.