C# — Как определить, существует ли раздел конфигурации в сопоставленном файле конфигурации EXE?

У меня есть проект C#, который считывается из автономного файла конфигурации с именем test.config. Это отдельный файл от обычного файла App.config.

Я пытаюсь определить, содержит ли файл test.config необязательное свойство TestProperty из кода. Я попытался использовать TestProperty.ElementInformation.IsPresent, но это всегда приводит к значению FLASE, даже если элемент раздела действительно существует.

class Program
{
    static void Main(string[] args)
    {
        string filePath = @"C:\Users\username\Desktop\TestProject\ConfigTestApp\Test.Config";
        ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap(filePath);
        fileMap.ExeConfigFilename = Path.GetFileName(filePath);

        Configuration config = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
        TestConfigSection section = config.GetSection("TestConfigSection") as TestConfigSection;
        bool isPresent = section.TestProperty.ElementInformation.IsPresent; // Why is this always false?
    }
}

Файл test.config выглядит так:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name ="TestConfigSection" type ="ConfigTestApp.TestConfigSection, ConfigTestApp"/>
  </configSections>

  <TestConfigSection>
    <TestProperty testvalue="testing 123" />
  </TestConfigSection>
</configuration>

Классы поддержки:

public class TestConfigSection : ConfigurationSection
{
    [ConfigurationProperty("TestProperty", IsRequired = true)]
    public TestConfigElement TestProperty
    {
        get
        {
            return base["TestProperty"] as TestConfigElement;
        }
    }
}

public class TestConfigElement : ConfigurationElement
{
    [ConfigurationProperty("testvalue", IsKey = true, IsRequired = true)]
    public string TestValue
    {
        get { return base["testvalue"] as string; }
        set { base["testvalue"] = value; }
    }
}

Если я перемещу раздел в App.config и использую ConfigurationManager.GetSection("TestConfigSection"), IsPresent работает нормально, но мне нужно, чтобы это работало из отдельного файла (test.config).

Есть ли способ заставить TestProperty.ElementInformation работать или любой другой способ определить, содержит ли файл test.config свойство TestProperty?


person Hooplator15    schedule 13.06.2019    source источник
comment
Я поместил это в модульный тест, запустил его, и это сработало для меня. Это заставляет меня задаться вопросом, могут ли у вас быть две версии файла. Вы можете осмотреть ElementInformation или SectionInformation для других подсказок. Раньше эта штука доставляла мне безумное горе. Возможно, вам будет намного проще просто прочитать файл JSON или что-то в этом роде и избавить себя от проблем, если это возможно.   -  person Scott Hannen    schedule 13.06.2019
comment
Интересно, это работало даже с разделом testconfig, помещенным в отдельный файл конфигурации xml? (То есть - не в app.config, а в отдельном файле с именем test.config)   -  person Hooplator15    schedule 13.06.2019
comment
Я использовал переменную, поэтому у меня был правильный путь для FileMap. Вот почему я ненавижу эти курсы. Если они не загружаются, я хочу исключение - не делать так, чтобы оно выглядело так, как будто оно загружено, но значения по умолчанию. Я уверен, что у них были свои причины, но это была огромная боль.   -  person Scott Hannen    schedule 13.06.2019


Ответы (1)


Возможно, это ваша проблема:

ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap(filePath);
fileMap.ExeConfigFilename = Path.GetFileName(filePath);

Разве ExeConfigFilename не должно быть полным путем к такому файлу?

fileMap.ExeConfigFilename = filePath;

Если это не проблема, мне недавно пришлось сделать что-то вроде вас, и вот что я сделал (используя данные вашего примера).

string filePath = @"C:\Users\username\Desktop\TestProject\ConfigTestApp\Test.Config";
ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap { ExeConfigFilename = filePath };
config = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
AppSettingsSection section = (AppSettingsSection) config.GetSection("TestConfigSection");

if ( section != null )
{
  string testValue = section .Settings["TestProperty"].Value;
}

В моем конфигурационном файле я использовал такой формат:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <TestConfigSection file="">
    <clear />
    <add key="TestProperty" value="testing 123" />
  </TestConfigSection>
</configuration>
person Jim Rhodes    schedule 13.06.2019
comment
Вот оно! Моя проблема заключалась в том, что я установил для fileMap.ExeconfigFileName имя файла, а не полный путь + имя файла. Хороший улов, спасибо! - person Hooplator15; 13.06.2019
comment
*** Кроме того, мне нужно добавить важное замечание: я не должен был вызывать перегрузку ExeConfigurationFileMap, которая принимает string machineConfigFileName И одновременно устанавливает fileMap.ExeConfigFileName! Это вызывало ошибку в моем коде с ошибкой. Запись «MyEntry» уже была добавлена. Я удалил ExeConfigurationFileMap(filePath) и заменил конструктором по умолчанию, и после этого он работал нормально. - person Hooplator15; 18.06.2019