Определение повторяющихся значений ключей в пользовательском разделе конфигурации app.config - PullRequest
1 голос
/ 19 октября 2011

У меня есть пользовательский раздел конфигурации, т.е. RegisterCompanies. Но имя ключа имеет одинаковое значение для двух записей. Когда я пытаюсь прочитать раздел конфигурации, я получаю ConfigurationerrorException, говоря, что ключевой элемент xxx уже добавлен. дубликаты ключей в нестандартной конфигурации. Ниже приведен раздел конфигурации, который я хочу добавить в файл app.config.

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

Ответы [ 4 ]

3 голосов
/ 19 октября 2011

Я думаю, вы должны сделать так:

<RegisterCompanies>
    <Companies>
      <Company name="Tata Motors">
          <Code name="Tata"/>
          <Code name="Honda"/>
      </Company>
    </Companies>
</RegisterCompanies>
1 голос
/ 19 октября 2011

Если ваша структура конфигурации похожа на это

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

0 голосов
/ 19 октября 2011

неприятным способом может быть замена ключа и кода в вашем xml

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

А затем повторно проанализируйте полученную коллекцию, чтобы исправить ситуацию, но, как было сказано ранее, это ОЧЕНЬ ГОРЯЧИЙ способ.

Поскольку вы определяете свой собственный блок конфигурации, вы должны иметь возможность предоставить сопоставление другому объекту коллекции (один принимает один и тот же ключ несколькими способами). Я думаю, что у меня есть что-то подобное, что регистрирует файл синтаксического анализатора раздела / рендерера для приложения ASP.NET. Посмотрим, смогу ли я найти его как можно скорее.

Начальные детали и довольно полный образец можно найти здесь

Привет

0 голосов
/ 19 октября 2011

Я бы предпочел изменить структуру данных, поэтому для каждой компании могут быть записи в режиме «Код», например:

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