在自定义配置部分app.config中定义重复键值

时间:2011-10-19 06:43:07

标签: c# app-config

我有一个自定义配置部分,即RegisterCompanies.But键名具有两个条目的相同值。当我尝试读取配置部分时,我得到ConfigurationerrorException,说已经添加了关键元素xxx。可以有人告诉我如何添加自定义配置中的重复键。 以下是我要添加到app.config的配置部分..

<RegisterCompanies>
    <Companies>
      <Company name="Tata Motors" code="Tata"/>
      <Company name="Tata Motors" code="Honda"/>
    </Companies>
  </RegisterCompanies>

4 个答案:

答案 0 :(得分:3)

我认为你应该这样做:

<RegisterCompanies>
    <Companies>
      <Company name="Tata Motors">
          <Code name="Tata"/>
          <Code name="Honda"/>
      </Company>
    </Companies>
</RegisterCompanies>

答案 1 :(得分:1)

如果你的配置结构是这样的

<RegisterCompanies>
    <Companies>
      <Company name="Tata Motors">
        <Codes>
          <Code name="Tata" />
          <Code name="Honda" />
        </Codes>
      </Company>
    </Companies>
  </RegisterCompanies>

然后你需要以下部分处理程序

public class CompaniesConfigurationHandler : IConfigurationSectionHandler
{
    public object Create(object parent, object configContext, XmlNode section)
    {
        var config = new CompaniesConfiguration();
        XmlNode xCompanies = section.SelectSingleNode("Companies");
        if (xCompanies == null)
            throw new ConfigurationErrorsException("Companies node not found");
        config.Companies = CreateCompanies(xCompanies);
        return config;
    }

    private static CompanyConfiguration[] CreateCompanies(XmlNode xCompanies)
    {
        var nodes = xCompanies.SelectNodes("Company");
        return nodes == null ?
                   new CompanyConfiguration[0]
                   : nodes.Cast<XmlNode>().Select(ReadCompany).ToArray();
    }

    private static CompanyConfiguration ReadCompany(XmlNode xCompany)
    {
        var company = new CompanyConfiguration();
        if (!((XmlElement) xCompany).HasAttribute("name"))
            throw new ConfigurationErrorsException("Company node must have name attribute", xCompany);
        company.Name = ((XmlElement) xCompany).GetAttribute("name");
        var codes = (XmlElement)xCompany.SelectSingleNode("Codes");
        company.Codes = ReadCodes(codes);
        return company;
    }

    private static string[] ReadCodes(XmlNode xElement)
    {
        XmlNodeList xItems = xElement.SelectNodes("Code");
        return xItems == null ?
                                  new string[0]
                   : xItems
                         .Cast<XmlElement>()
                         .Where(xItem => xItem.HasAttribute("name"))
                         .Select(xItem => xItem.GetAttribute("name"))
                         .ToArray();
    }
}

public class CompanyConfiguration
{
    public string Name { get; set; }
    public string[] Codes { get; set; }
}

public class CompaniesConfiguration
{
    public CompanyConfiguration[] Companies { get; set; }
}

易于peasy。

答案 2 :(得分:0)

我更愿意更改数据结构,因此每个公司都可以使用这种模式“代码”条目

   <RegisterCompanies>
    <Companies>
      <Company name="Tata Motors"/>
      <Codes>
        <Code name="Tata" />
        <Code name="Honda" />
      </Codes>
    </Companies>
  </RegisterCompanies>

答案 3 :(得分:0)

一种讨厌的方式可能是在xml中交换密钥和代码

<RegisterCompanies>
    <Companies>
      <Company code="Tata Motors" name="Tata"/>
      <Company code="Tata Motors" name="Honda"/>
    </Companies>
  </RegisterCompanies>

然后重新解析生成的集合以修复问题,但如前所述,这是一种非常繁琐的方式。

由于您正在定义自己的配置块,因此您应该能够将映射提供给不同的集合对象(一个以多种方式接受相同的密钥)。我想我有类似的东西,它为ASP.NET应用程序注册了section file parser / renderer。看看我是否能尽快找到它。

可以找到初始详细信息和完整的示例here

此致