Подтвердить что ты не робот

Пользовательская настройка, 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"]; } }
    }
}
4b9b3361

Ответ 1

Я нашел, что лучший способ - переопределить 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.

Ответ 2

2 вещи, которые я могу придумать с головы, будут использовать DefaultValue, например:

    [ConfigurationProperty("customsettingitem", DefaultValue = -1)]
    public int CustomSettingItem { get { return (int)this["customsettingitem"]; } }

Предполагая наличие недопустимого значения. В этом случае CustomSettingItem == -1 означает, что он не был установлен, a >= 0 было значением, установленным в config. Конечно, это предполагает, что -1 не был действительным входом.

Вторая идея состоит в том, чтобы вместо этого использовать nullable int:

    [ConfigurationProperty("customsettingitem", IsRequired = false)]
    public int? CustomSettingItem { get { return (int?)this["customsettingitem"]; } }

Теперь, если ничего не задано в config, оно должно иметь значение null вместо 0.

Ответ 3

Попробуйте следующее:

configElement.ElementInformation.Properties[propName].ValueOrigin = 
        PropertyValueOrigin.SetHere

Свойство ValueOrigin сообщает вам, откуда оно берется.

Ответ 4

До сих пор я не мог указать свойство null, если оно не определено в файле конфигурации. Похоже, что в этом бесконечная мудрость 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; }
    }

Это взломать и неправильно пометить свойство по мере необходимости. Если вы используете инструмент для редактирования файла конфигурации, ему это не понравится.

Ответ 5

Вы также можете проверить, используя следующее:

config.Setting1.CustomSettingItem.ElementInformation.IsPresent 

он предоставит вам значение false, если оно не было найдено в вашем файле конфигурации.