У меня есть консольное приложение, которое пытается загрузить CustomConfigurationSection из web.config файла.
Раздел пользовательской конфигурации имеет элемент пользовательской конфигурации, который требуется. Это означает, что, когда я загружаю раздел конфигурации, я ожидаю видеть исключение, если тот элемент конфигурации не будет присутствовать в конфигурации. Проблема состоит в том, что платформа.NET, кажется, полностью игнорирует атрибут isRequired. Таким образом, когда я загружаю раздел конфигурации, я просто создаю экземпляр элемента пользовательской конфигурации и устанавливаю его на разделе конфигурации.
Мой вопрос, почему это происходит? Я хочу, чтобы GetSection () метод запустил исключение ConfigurationErrors, так как необходимый элемент отсутствует в конфигурации.
Вот то, как мой раздел конфигурации смотрит.
public class MyConfigSection : ConfigurationSection
{
[ConfigurationProperty("MyConfigElement", IsRequired = true)]
public MyConfigElement MyElement
{
get { return (MyConfigElement) this["MyConfigElement"]; }
}
}
public class MyConfigElement : ConfigurationElement
{
[ConfigurationProperty("MyAttribute", IsRequired = true)]
public string MyAttribute
{
get { return this["MyAttribute"].ToString(); }
}
}
Вот то, как я загружаю раздел конфигурации.
class Program
{
public static Configuration OpenConfigFile(string configPath)
{
var configFile = new FileInfo(configPath);
var vdm = new VirtualDirectoryMapping(configFile.DirectoryName, true, configFile.Name);
var wcfm = new WebConfigurationFileMap();
wcfm.VirtualDirectories.Add("/", vdm);
return WebConfigurationManager.OpenMappedWebConfiguration(wcfm, "/");
}
static void Main(string[] args)
{
try{
string path = @"C:\Users\vrybak\Desktop\Web.config";
var configManager = OpenConfigFile(path);
var configSection = configManager.GetSection("MyConfigSection") as MyConfigSection;
MyConfigElement elem = configSection.MyElement;
} catch (ConfigurationErrorsException ex){
Console.WriteLine(ex.ToString());
}
}
Вот то, на что похож мой файл конфигурации.
<?xml version="1.0"?>
<configuration>
<configSections>
<section name="MyConfigSection" type="configurationFrameworkTestHarness.MyConfigSection, configurationFrameworkTestHarness" />
</configSections>
<MyConfigSection>
</MyConfigSection>
Странная часть - то, что, если я открываю файл конфигурации и загружаю раздел 2 раза подряд, я получу исключение, которое я ожидаю.
var configManager = OpenConfigFile(path);
var configSection = configManager.GetSection("MyConfigSection") as MyConfigSection;
configManager = OpenConfigFile(path);
configSection = configManager.GetSection("MyConfigSection") as MyConfigSection;
Если я буду использовать код выше, то исключение запустит и скажет мне, что MyConfigElement требуется. Вопрос состоит в том, Почему он не выдает это исключение в первый раз??
Я обнаружил, что лучший обходной путь для этого - вручную перебирать все вложенные свойства типа ConfigurationElement и проверять их самостоятельно после получения раздела. Если элемент требуется, но его нет в файле, я просто генерирую исключение ConfigurationErrorsException.
Вот мой код.
private void ProcessMissingElements(ConfigurationElement element)
{
foreach (PropertyInformation propertyInformation in element.ElementInformation.Properties)
{
var complexProperty = propertyInformation.Value as ConfigurationElement;
if (complexProperty == null)
continue;
if (propertyInformation.IsRequired && !complexProperty.ElementInformation.IsPresent)
throw new ConfigurationErrorsException("ConfigProperty: [{0}] is required but not present".FormatStr(propertyInformation.Name));
if (!complexProperty.ElementInformation.IsPresent)
propertyInformation.Value = null;
else
ProcessMissingElements(complexProperty);
}
}
Эрик ответил на этот на форумах MS
Процитирую его ответ:
Член IsRequired из ConfigurationPropertyAttribute не работает при применении к дочернему объекту (производному от ConfigurationElement)
Вы пытались назначить его напрямую правильному типу переменной, то есть MyConfigSection вместо var? Это единственное различие, которое я вижу между двумя строками кода. (т.е. во второй строке var теперь имеет определенный тип).