app.config - 配置系统无法使用自定义部分进行初始化

app.config - configuration system failed to initialize with custom section

我有一个网站 api,我在其中根据此 link:https://msdn.microsoft.com/en-us/library/2tw134k3.aspx 在 web.config 中添加了一个自定义部分。我的 web.config 看起来如下:

<?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>

我在 configSections 和 productGroup 中添加了。然后,我将 c# class 定义为 ProductSection,如下所示:

使用 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;
            }
        }
    }
}

我已经将这 2 个部分复制到我的测试项目中的 app.config,但是当我现在尝试调试测试时,我遇到了初始化失败错误。当我注释掉 productGroup 部分时,它就会停止抱怨。我做错了什么?

更新

作为旁注,我最终将其结构简化了一些。由于我的 'product' 部分只需要一个名称和 ID,它们根据 appSettings 将自己借给键值对。所以我创建了一个这样的部分:

<configSections>
  <section name="productGroup"
           type="System..Configuration.NameValueSectionHandler"
           allowLocation="true"
           allowDefinition="Everywhere"/>
</configSections>

请注意,我更改了类型。我的 productGroup 看起来像这样:

<productGroup>
  <add key="product1" value="1" />
  <add key="product2" value="2" />
</productGroup>

然后我可以完全删除 ProductSection class 并像这样引用我的产品组:

var products = ConfigurationManager.GetSection("productGroup") as NameValueCollection;

if (products.AllKeys.Contains(myProduct))
{
    var myValue = products[myProduct];
}    

我注意到两件事

配置部分在配置文件中只能出现 1 次。
完整的初始化异常显示:

System.Configuration.ConfigurationErrorsException: Configuration system failed to initialize ---> System.Configuration.ConfigurationErrorsException: Sections must only appear once per config file.

这意味着您只能有 1 个 product 部分:

<productGroup>
    <product name="my name" id="1" />       
</productGroup>

如果需要多个,则需要使用唯一的节名称声明多个节:

<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>

最佳做法是在 app/web.config 中声明节及其 完全限定的程序集名称
其中包括程序集的名称(没有文件扩展名)。
如果 class/section 是在外部程序集中定义的,则这是必须的;这里 ProductionSection 是在主要单元测试以外的程序集中定义的。

在单元测试项目的 App.config 文件中声明如下部分。
(将 NameOfTheAssemblyContainingTheProductSectionClass 替换为您的程序集名称。

<section
    name="product"
    type="myProject.Stuff.Api.ProductSection, NameOfTheAssemblyContainingTheProductSectionClass"             
    />