自定义配置、ConfigurationElements 和 ConfigurationProperties

发布于 2024-07-13 12:20:18 字数 1366 浏览 7 评论 0原文

过去三天我一直在网上搜寻,但找不到任何有关此问题的参考资料。 我创建了一个与我的 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"]; } }
    }
}

I've been scouring the net for the last 3 days, and can't find any reference to this question. I've created a custom configuration class to be used with my app.config. Everything works fine. The problem comes in when a configuration property (of a configuration element) is not required, and is not defined in the app.config. It seems that default values are returned for the configuration property. Does anyone know how to determine if the property isn't defined in the app.config? (I've been trying to post my app.config, but can't figure out how to do it...anyone know how?)


//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"]; } }
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

你的往事 2024-07-20 12:20:18

我发现最好的方法是重写 ConfigurationSection.PostDeserialize() 并检查从 ConfigurationElement 派生的每个节成员的 IsPresent 属性。

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

I found the best way is to override ConfigurationSection.PostDeserialize() and check the IsPresent property of each section member that derives from 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();
    }
}

Each ConfigurationElement that has not been read from the config file will be null afterwards.

花之痕靓丽 2024-07-20 12:20:18

我能立即想到的两件事是使用 DefaultValue,如下所示:

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

假设有一些值无效。 在本例中,CustomSettingItem == -1 表示未设置,而 >= 0 是在 config.xml 中设置的值。 当然,假设 -1 首先不是有效输入。

第二个想法是使用可空 int 来代替:

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

现在如果配置中没有设置任何内容,则它应该默认为 null 而不是 0。

The 2 things I can think of off the top of my head would be to use a DefaultValue, like so:

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

Assuming there is some value that is invalid. In this case, CustomSettingItem == -1 means it wasnt set, and >= 0 was a value set in config. Of course that assumes -1 wasnt valid input in the first place.

Second idea is to use a nullable int instead:

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

Now if nothing is set in config, it should default to null instead of 0.

南城追梦 2024-07-20 12:20:18

请尝试以下操作:

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

ValueOrigin 属性告诉您该值来自哪里。

Try the following:

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

The ValueOrigin property tells you where does the value come from.

少钕鈤記 2024-07-20 12:20:18

到目前为止,如果配置文件中未定义属性,我还无法将其告知为空。 看起来,微软以无限的智慧决定,当您键入 null 时,您真正指的是 String.Empty 或 new ConfigurationElement() 。

我目前解决这个问题的方法是这样的:

    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; }
    }

这是一种黑客行为,会错误地根据需要标记属性。 如果您使用工具来编辑配置文件,则不会这样。

So far I've not been able to tell a property to be null if it isn't defined in the configuration file. It seems that in it's infinite wisdom, Microsoft decided you really mean String.Empty or new ConfigurationElement() when you type null.

The way I'm currently solving it is like this:

    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; }
    }

It's a hack and will wrongly mark the property as required. If you're using a tool to edit your configuration file it won't like this.

遗弃M 2024-07-20 12:20:18

您还可以使用以下命令进行检查:

config.Setting1.CustomSettingItem.ElementInformation.IsPresent 

如果在您的配置文件中找不到它,它会给您错误。

You can also check using the following:

config.Setting1.CustomSettingItem.ElementInformation.IsPresent 

it will give you false if it was not found in your config file.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文