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

Posted

技术标签:

【中文标题】为啥我不能将属性转换为嵌套元素?【英文标题】:Why can't I convert attribute to nested element?为什么我不能将属性转换为嵌套元素? 【发布时间】:2012-01-06 08:10:30 【问题描述】:

我正在从“App.config”读取设置。我刚刚弄清楚如何使用ConfigurationSectionConfigurationElementCollectionConfigurationelElement

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>

我的 C# 代码:

public class MailTemplateSection : ConfigurationSection

    [ConfigurationProperty("items", IsDefaultCollection = false)]
    public MailTemplateCollection MailTemplates
    
        get  return (MailTemplateCollection)this["items"]; 
        set  this["items"] = value; 
    


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


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; 
    


和工作代码:

class Program

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

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

    

当我在 xml 中将字段声明为属性时,一切正常。但是当我尝试将属性转换为嵌套元素时 - “Property 'Body' is not a ConfigurationElement” 发生错误。

我做错了什么?

【问题讨论】:

参考这个how to use text element instead of attribute in custom configuration 【参考方案1】:

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

public class Body : ConfigurationElement

    [ConfigurationProperty("value", DefaultValue = "Body", IsKey = true, IsRequired = true)]
    public string Valueget;set;

这样你就可以写了

<body value="some val"/>

在您的配置中。

【讨论】:

弗拉基米尔,我想将大文本存储在“body”属性中,然后不想将这些数据存储在属性中。恕我直言,大数据必须存储在标签内。 大文本根本不应该存储在 App.config 中。使用数据库或自定义格式。它可能很容易成为 XmlSerializer 生成的格式,您可以为其创建类并完全控制数据的序列化方式。 如此令人沮丧,有多少次人们没有响应原始请求,认为这不是要走的路。在这种情况下,可能有很多理由使用元素而不是属性,例如使用 CDATA……

以上是关于为啥我不能将属性转换为嵌套元素?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我应该“将 myVariable 转换为最终的一个元素数组”?

为啥 []string 不能在 golang 中转换为 []interface [重复]

为啥我不能将数字转换为双精度数?

为啥我不能将 str 列表转换为浮点列表?

为啥 math.inf 是浮点数,为啥我不能将其转换为整数?

将嵌套列表中的元素转换为数据框