I've got a web api where I've added a custom section into the web.config as per this link: https://msdn.microsoft.com/en-us/library/2tw134k3.aspx. My web.config looks as follows:
<?xml version="1.0" encoding="utf-8"?>
<!--
For more information on how to configure your ASP.NET application, please
visit https://go.microsoft.com/fwlink/?LinkId=301879
-->
<configuration>
<configSections>
<sectionGroup name="productGroup">
<section
name="product"
type="myProject.Stuff.Api.ProductSection"
allowLocation="true"
allowDefinition="Everywhere"
/>
</sectionGroup>
</configSections>
<appSettings>
<!-- various app settings -->
</appSettings>
<productGroup>
<product name="my name" id="1" />
<product name="my name 2" id="2" />
</productGroup>
<!-- other standard elements -->
</configuration>
I added in the configSections and the productGroup. I then define a c# class as ProductSection as follows:
using System.Configuration;
namespace myProject.Stuff.Api
{
public class ProductSection : ConfigurationSection
{
[ConfigurationProperty("name", IsRequired = true)]
public string Name
{
get
{
return (string)this["name"];
}
set
{
this["name"] = value;
}
}
[ConfigurationProperty("id", IsRequired = true)]
public int Id
{
get
{
return (int)this["id"];
}
set
{
this["id"] = value;
}
}
}
}
I've copied the 2 sections across to my app.config in my test project, but when I now try and debug a test I get the failed to initialize error. When I comment out the productGroup section it then stops complaining. What have I done wrong?
UPDATE
As a side note I ended up structuring it a little more simply. As my 'product' sections only needed a name and id they lent themselves to key value pairs as per appSettings. So I created a section like this:
<configSections>
<section name="productGroup"
type="System..Configuration.NameValueSectionHandler"
allowLocation="true"
allowDefinition="Everywhere"/>
</configSections>
Note that I changed the type. My productGroup then looked like this:
<productGroup>
<add key="product1" value="1" />
<add key="product2" value="2" />
</productGroup>
I then could remove the ProductSection class altogether and just reference my group of products like this:
var products = ConfigurationManager.GetSection("productGroup") as NameValueCollection;
if (products.AllKeys.Contains(myProduct))
{
var myValue = products[myProduct];
}
I notice 2 things
A configuration section can only appear 1 time within a configuration file.
The full initialization exception shows:
System.Configuration.ConfigurationErrorsException: Configuration system failed to initialize ---> System.Configuration.ConfigurationErrorsException: Sections must only appear once per config file.
This means you can only have 1 product
section:
<productGroup>
<product name="my name" id="1" />
</productGroup>
If you need multiple, you need to declare multiple sections with unique section names:
<configuration>
<sectionGroup name="productGroup">
<section name="product" type="myProject.Stuff.Api.ProductSection" />
<section name="product2" type="myProject.Stuff.Api.ProductSection" />
</sectionGroup>
<!-- Other configuration elements -->
<productGroup>
<product name="my name" id="1" />
<product2 name="my name 2" id="2" />
</productGroup>
</configuration>
It is a best practice to declare the section in app/web.config
with its fully qualified assemblyname,
which includes the name of the assembly (without file extension).
This is a must if the class/section is defined in an external assembly; here ProductionSection
is defined in an assembly other than the one of the main unittest.
Declare the section as below in the App.config
file of your unittest project.
(Replace NameOfTheAssemblyContainingTheProductSectionClass with the name of your assembly.)
<section
name="product"
type="myProject.Stuff.Api.ProductSection, NameOfTheAssemblyContainingTheProductSectionClass"
/>