Пользовательская конфигурация, ConfigurationElements и ConfigurationProperties
Я рыскал в сети последние 3 дня и не могу найти ссылку на этот вопрос. Я создал собственный класс конфигурации для использования с моим app.config. Все отлично работает Проблема возникает, когда свойство конфигурации (элемента конфигурации) не требуется и не определено в app.config. Кажется, что значения по умолчанию возвращаются для свойства конфигурации. Кто-нибудь знает, как определить, не определено ли свойство в app.config? (Я пытался опубликовать свой app.config, но не могу понять, как это сделать... кто-нибудь знает, как?)
//Main
namespace TestStub
{
class Program
{
static void Main(string[] args)
{
CustomSettingsHandler config = (CustomSettingsHandler)ConfigurationManager.GetSection("CustomSettingsManager");
Console.WriteLine("Setting1 {0}", config.Setting1.CustomSettingItem);
Console.WriteLine("Setting2 {0}", config.Setting2.CustomSettingItem);
}
}
}
//Custom Configuration Class
namespace CustomConfiguration
{
public class CustomSettingsHandler : ConfigurationSection
{
[ConfigurationProperty("setting1", IsRequired = false)]
public CustomSettingElement Setting1 { get { return (CustomSettingElement)this["setting1"]; } }
[ConfigurationProperty("setting2", IsRequired = false)]
public CustomSettingElement Setting2 { get { return (CustomSettingElement)this["setting2"]; } }
}
public class CustomSettingElement : ConfigurationElement
{
[ConfigurationProperty("customsettingitem", IsRequired = false)]
public int CustomSettingItem { get { return (int)this["customsettingitem"]; } }
}
}
5 ответов
Я нашел лучший способ переопределить ConfigurationSection.PostDeserialize()
и проверить IsPresent
свойство каждого члена секции, которое происходит от ConfigurationElement
,
public class CustomSettingsHandler : ConfigurationSection
{
// ...
protected override void PostDeserialize()
{
foreach (ConfigurationProperty property in Properties)
{
var configElement = this[property] as ConfigurationElement;
if (configElement != null
&& !configElement.ElementInformation.IsPresent)
{
this[property] = null;
}
}
base.PostDeserialize();
}
}
каждый ConfigurationElement
который не был прочитан из файла конфигурации будет null
после этого.
Две вещи, которые я могу придумать, - использовать DefaultValue, например, так:
[ConfigurationProperty("customsettingitem", DefaultValue = -1)]
public int CustomSettingItem { get { return (int)this["customsettingitem"]; } }
Предполагая, что есть какое-то значение, которое является недействительным. В этом случае CustomSettingItem == -1 означает, что он не был установлен, а>= 0 было значением, установленным в конфигурации. Конечно, это предполагает, что -1 не был допустимым вводом в первую очередь.
Вторая идея - вместо этого использовать обнуляемый тип int:
[ConfigurationProperty("customsettingitem", IsRequired = false)]
public int? CustomSettingItem { get { return (int?)this["customsettingitem"]; } }
Теперь, если в конфиге ничего не установлено, по умолчанию он должен быть нулевым, а не 0.
Попробуйте следующее:
configElement.ElementInformation.Properties[propName].ValueOrigin =
PropertyValueOrigin.SetHere
ValueOrigin
свойство говорит вам, откуда берется значение.
Вы также можете проверить, используя следующее:
config.Setting1.CustomSettingItem.ElementInformation.IsPresent
это даст вам ложь, если он не был найден в вашем конфигурационном файле.
До сих пор я не смог указать свойству быть нулевым, если оно не определено в файле конфигурации. По всей видимости, Microsoft решила, что вы действительно имеете в виду String.Empty или новый ConfigurationElement(), когда набираете null.
То, как я сейчас решаю это так:
bool _hasProp = true;
protected override object OnRequiredPropertyNotFound(string name)
{
if (name == "prop")
{
_hasProp = false;
return null; // note that this will still not make prop null
}
return base.OnRequiredPropertyNotFound(name);
}
[ConfigurationProperty("prop", IsRequired = true)]
public string Prop
{
get { return _hasProp ? (string) this["prop"] : null; }
}
Это взломать и будет неправильно помечать свойство как требуется. Если вы используете инструмент для редактирования файла конфигурации, он не понравится.