为什么我不能将属性转换为嵌套元素?

lew*_*wis 6 .net c# xml app-config

我正在从'App.config'中读取设置.我只是想出了如何使用ConfigurationSection,ConfigurationElementCollectionConfigurationelElement.

App.config中:

<?xml version="1.0" encoding="utf-8" ?>
<configuration> 
    <configSections>
        <sectionGroup name="notificationSettingsGroup">
                <section name="mailTemplates" type="Project.Lib.Configuration.MailTemplateSection, Project.Lib"
                    allowDefinition="Everywhere" allowExeDefinition="MachineToApplication" requirePermission="false"/>
        </sectionGroup>         
    </configSections>
    <notificationSettingsGroup>
        <mailTemplates>
            <items>
                <mailTemplate name="actionChain" subject="Subject bla-bla">
                    <body>Body bla-bla</body>
                </mailTemplate>                 
            </items>
        </mailTemplates>
    </notificationSettingsGroup>
    <startup>
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
    </startup>  
</configuration>
Run Code Online (Sandbox Code Playgroud)

我的C#代码:

public class MailTemplateSection : ConfigurationSection
{
    [ConfigurationProperty("items", IsDefaultCollection = false)]
    public MailTemplateCollection MailTemplates
    {
        get { return (MailTemplateCollection)this["items"]; }
        set { this["items"] = value; }
    }
}
Run Code Online (Sandbox Code Playgroud)
[ConfigurationCollection(typeof(MailTemplateElement), AddItemName = "mailTemplate",
    CollectionType = ConfigurationElementCollectionType.AddRemoveClearMap)]
public class MailTemplateCollection : ConfigurationElementCollection
{
    protected override ConfigurationElement CreateNewElement()
    {
        return new MailTemplateElement();
    }

    protected override object GetElementKey(ConfigurationElement element)
    {
        return ((MailTemplateElement) element).Name;
    }
}
Run Code Online (Sandbox Code Playgroud)
public class MailTemplateElement : ConfigurationElement
{
    [ConfigurationProperty("name", DefaultValue = "action", IsKey = true, IsRequired = true)]
    public string Name
    {
        get { return (string)this["name"]; }
        set { this["name"] = value; }
    }

    [ConfigurationProperty("subject", DefaultValue = "Subject", IsKey = false, IsRequired = true)]
    public string Subject
    {
        get { return (string)this["subject"]; }
        set { this["subject"] = value; }
    }

    [ConfigurationProperty("body", DefaultValue = "Body", IsKey = false, IsRequired = true)]
    public string Body
    {
        get { return (string)this["body"]; }
        set { this["body"] = value; }
    }
}
Run Code Online (Sandbox Code Playgroud)

和工作代码:

class Program
{
    static void Main(string[] args)
    {
        Configuration config =
            ConfigurationManager.OpenExeConfiguration(
            ConfigurationUserLevel.None);

        var mailTemplatesSection =
           config.GetSection("notificationSettingsGroup/mailTemplates") as MailTemplateSection;

    }
}
Run Code Online (Sandbox Code Playgroud)

当我在xml中将字段声明为属性时,所有工作都有效.但是当我尝试将属性转换为嵌套元素时 - "Property'Body'不是ConfigurationElement"会发生错误.

我究竟做错了什么?

Vla*_*lov 2

因为您必须创建自定义类型并从 ConfigurationElement 派生它们,才能将它们用作配置文件中的元素。所有简单类型始终写为属性。例如:

public class Body : ConfigurationElement
{
    [ConfigurationProperty("value", DefaultValue = "Body", IsKey = true, IsRequired = true)]
    public string Value{get;set;}
}
Run Code Online (Sandbox Code Playgroud)

这将允许你写

<body value="some val"/>
Run Code Online (Sandbox Code Playgroud)

在你的配置中。

  • 大文本根本不应该存储在 App.config 中。使用数据库或自定义格式。它很容易成为 XmlSerializer 生成的格式,您可以为其创建类并完全控制数据的序列化方式。 (3认同)