2010-11-03 2 views
7

У меня возникла эта странная проблема ... в моем коде установлено ли значение IsRequired на false или true, тогда оно остается ложным. Однако если я ставлю DefaultValue, это сработает?C# - ConfigurationSection isRequired атрибут

Неработающая код:

public class FtpSettingsSection : ConfigurationSection 
{ 
    [ConfigurationProperty("host", IsRequired = true)] 
    public HostElement Host 
    { 
     get { return (HostElement)this["host"]; } 
     set { this["host"] = value; } 
    } 

} 

public class HostElement : ConfigurationElement 
{ 
    [ConfigurationProperty("URL", IsRequired = true)] 
    public string URL 
    { 
     get { return (string)this["URL"]; } 
     set { this["URL"] = value; } 
    } 
} 

и рабочий код:

public class FtpSettingsSection : ConfigurationSection 
{ 
    [ConfigurationProperty("host", DefaultValue = "", IsRequired = true)] 
    public HostElement Host 
    { 
     get { return (HostElement)this["host"]; } 
     set { this["host"] = value; } 
    } 

} 

public class HostElement : ConfigurationElement 
{ 
    [ConfigurationProperty("URL", DefaultValue = "", IsRequired = true)] 
    public string URL 
    { 
     get { return (string)this["URL"]; } 
     set { this["URL"] = value; } 
    } 
} 

Как получилось, что мне нужно установить DefaultValue на ""?

ответ

0

Я предполагаю, что у вас нет значения свойства URL-адреса в вашей конфигурации. Поэтому, когда конфигурация загружается, ConfigurationManager проверяет атрибуты, чтобы узнать, требуется ли значение свойства, а затем выбрасывает исключение, если не находит значения. Если установлено значение по умолчанию, то это значение используется, если в конфигурации не найдено ни одного.

+1

Первый пример кода dosent исключает любое исключение, даже если свойство хоста не определено в файле конфигурации? – ebb

+0

Первый пример будет генерировать исключение, второй с атрибутом по умолчанию - нет. – dexter

+0

На самом деле я протестировал это, и пример FIRST не генерирует исключение. В тестовой консоли приложение IsRequired, похоже, игнорируется. Если он IsRequired, вы не должны ставить значение по умолчанию, потому что тогда это действительно не требуется. Если вы указали значение IsRequired = true, тогда он должен выдать исключение, если вы не предоставили значение по умолчанию, но это не так. Я тестировал в .Net 4. –

6

Я столкнулся с одной проблемой и нашел решение здесь http://msdn.microsoft.com/en-us/library/system.configuration.configurationpropertyattribute%28v=vs.90%29.aspx#1. Комментарий на ConfigurationPropertyAttribute не совсем правильно, но это объясняет основу проблемы:

IsRequired член ConfigurationPropertyAttribute не работает применительно к дочернему объекту (вытекающему из ConfigurationElement). Когда подсистема отражает атрибуты родительского раздела/элемента, чтобы определить, какие свойства конфигурации определены, он создаст новый экземпляр (соответствующего типа) для каждого дочернего элемента и сохранит его в списке значений родителя. Позже, когда он проверяет, были ли указаны все необходимые свойства или нет, он не может различать инициализированный дочерний элемент по умолчанию и тот, который явно содержится в файле конфигурации.

Наиболее оптимальным решением было бы программное объявление необходимых элементов через класс ConfigurationProperty. Для этого требуется значительно большая работа, чем декларативный подход. Альтернатива ...

Насколько я могу судить, альтернатива неверна.

Пример программной модели можно найти на странице ConfigurationProperty. Мне удалось решить проблему для себя, объявив необходимые мне свойства в конструкторе моего пользовательского элемента и оставив все остальное одинаковым.

Я подозреваю, что на самом деле он не работает, когда вы добавляете DefaultValue, но скорее бросаете исключение по другой причине. Вам нужно будет развернуться до конца цепи InnerException, чтобы найти ConfigurationErrorsException. Правильное сообщение, когда отсутствует требуемое свойство, - «Требуемый атрибут« хост »не найден. (C: \ path \ to \ yourproject \ bin \ Debug \ yourproject.vshost.exe.Config line ##)"

Когда вы укажете пустое значение по умолчанию для строки, подсистема конфигурации попытается проанализировать эту строку в HostElement и выполнить сбой. В результате ConfigurationErrorsException имеет сообщение «Значение по умолчанию для« хозяина »не может быть проанализировано. Ошибка: ссылка объекта не установлена ​​в экземпляр объекта. (C: \ path \ to \ yourproject \ bin \ Debug \ yourproject.vshost.exe.Config line ##) "

3

Извините за некропостинг, но эта проблема ударила меня тоже, но более странным образом, и мое решение также относится к заданному вопросу.

Я реализовал перезагрузку конфигурации без перезапуска процесса. При запуске процесса атрибут IsRequired «проигнорирован», а параметр ConfigurationElement молча инициализируется значениями по умолчанию. Но когда перезагружается конфигурация, уважается IsRequired! Поэтому я жестко запрограммировал перезагрузку конфигурации при запуске процесса и решил проблему отсутствия исключения!

псевдокод:

config = (SampleConfiguration)ConfigurationManager.GetSection(ConfigSectionName); 
// <-- no exception thrown for missing required properties 

ConfigurationManager.RefreshSection(ConfigSectionName); 

config = (SampleConfiguration)ConfigurationManager.GetSection(ConfigSectionName); 
// <-- exception thrown! 
2

выкапывать мертвых нить. Но я случайно нашел для этого работу.

В своем конструкторе пользовательского раздела сделайте ссылку на элемент ElementInformation пользовательского элемента. Таким образом, другой экземпляр вашего настраиваемого раздела будет создан в контексте элемента. И почему-то, что я не понимаю полностью, свойство IsRequired выполнено.

public class FtpSettingsSection : ConfigurationSection 
{ 
    public FtpSettingsSection() 
    { 
     // force it to double load. 
     if (this.Host.ElementInformation.IsPresent) ; 
    } 

    [ConfigurationProperty("host", IsRequired = true)] 
    public HostElement Host 
    { 
     get { return (HostElement)this["host"]; } 
     set { this["host"] = value; } 
    } 
} 
Смежные вопросы