使用嵌套集合正确实现自定义配置部分? [英] Correct implementation of a custom config section with nested collections?

查看:24
本文介绍了使用嵌套集合正确实现自定义配置部分?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 Web 应用程序中,我希望能够使用这样的配置部分定义一些映射:

<预><代码><配置><configSections><sectionGroup name="MyCustomer"><section name="CatalogMappings" type="MyCustom.MyConfigSection"/></sectionGroup></configSections><我的客户><目录映射><目录名称=toto"><mapping value="1" displayText="titi"/><mapping value="2" displayText="tata"/></目录><目录名称=toto2"><mapping value="1" displayText="titi2"/><mapping value="2" displayText="tata2"/></目录></catalogMappings></我的客户></配置>

我正在努力实现这个目标,尤其是在定义我的收藏集时.为了实现这一目标,我需要实现哪些类?

目前,我有:

公共类 CatalogMappingSection : System.Configuration.ConfigurationSection{公共类映射:ConfigurationElement{[ConfigurationProperty("externalKey")]公共字符串 ExternalKey { 获取;放;}[ConfigurationProperty("displayText", IsRequired=true)]公共字符串 DisplayText { 获取;放;}[ConfigurationProperty("value", IsRequired=true, IsKey=true)]公共 int 值 { 得到;放;}}公共类目录:ConfigurationElementCollection{[ConfigurationProperty("name", IsRequired=true, IsKey=true)]公共字符串名称 { 获取;放;}受保护的覆盖 ConfigurationElement CreateNewElement(){返回新映射();}受保护的覆盖对象 GetElementKey(ConfigurationElement 元素){返回((映射)元素).值;}}公共类 CatalogCollection : ConfigurationElementCollection{[配置属性(目录")][ConfigurationCollection(typeof(Catalog))]公共目录 CatalogMappingCollection{得到{返回(目录)base[目录"];}}受保护的覆盖 ConfigurationElement CreateNewElement(){返回新目录();}受保护的覆盖对象 GetElementKey(ConfigurationElement 元素){return ((Catalog)element).Name;}}[ConfigurationProperty("catalogMappings")][ConfigurationCollection(typeof(CatalogCollection))]公共目录集合目录映射{得到{返回 (CatalogCollection)base["catalogMappings"];}}}

但是,这并没有按预期工作.

解决方案

我终于找到了这个人的例子.它经过编码,开箱即用.

http://manyrootsofallevilrants.blogspot.com/2011/07/nested-custom-configuration-collections.html

我要把代码贴在这里……只是因为当有人说你的答案在这里"时我无法忍受,而且链接已经死了.

请先尝试他的网站,如果有效,请留下谢谢".

<块引用>

使用系统;使用 System.Configuration;命名空间 SSHTunnelWF{公共类 TunnelSection :配置部分{[ConfigurationProperty("", IsDefaultCollection = true)]公共 HostCollection 隧道{得到{HostCollection hostCollection = (HostCollection)base[""];返回主机集合;}}}公共类 HostCollection : ConfigurationElementCollection{公共主机集合(){HostConfigElement 详细信息 = (HostConfigElement)CreateNewElement();if (details.SSHServerHostname != ""){添加(详细信息);}}公共覆盖 ConfigurationElementCollectionType CollectionType{得到{返回 ConfigurationElementCollectionType.BasicMap;}}受保护的覆盖 ConfigurationElement CreateNewElement(){返回新的 HostConfigElement();}受保护的覆盖对象 GetElementKey(ConfigurationElement 元素){return ((HostConfigElement)element).SSHServerHostname;}public HostConfigElement this[int index]{得到{返回(HostConfigElement)BaseGet(索引);}放{if (BaseGet(index) != null){BaseRemoveAt(索引);}BaseAdd(索引,值);}}新的公共 HostConfigElement this[字符串名称]{得到{返回(HostConfigElement)BaseGet(名称);}}public int IndexOf(HostConfigElement 详细信息){返回 BaseIndexOf(详细信息);}公共无效添加(HostConfigElement 详细信息){基地添加(详细信息);}protected override void BaseAdd(ConfigurationElement element){BaseAdd(元素,假);}公共无效删除(HostConfigElement 详细信息){如果(BaseIndexOf(详细信息)> = 0)BaseRemove(details.SSHServerHostname);}public void RemoveAt(int index){BaseRemoveAt(索引);}公共无效删除(字符串名称){BaseRemove(名称);}公共无效清除(){基本清除();}受保护的覆盖字符串 ElementName{得到 { 返回主机";}}}公共类 HostConfigElement:ConfigurationElement{[ConfigurationProperty("SSHServerHostname", IsRequired = true, IsKey = true)][StringValidator(InvalidCharacters = " ~!@#$%^&*()[]{}/;’"|\")]公共字符串 SSHServerHostname{get { return (string)this["SSHServerHostname"];}set { this["SSHServerHostname"] = value;}}[ConfigurationProperty("username", IsRequired = true)][StringValidator(InvalidCharacters = " ~!@#$%^&*()[]{}/;’"|\")]公共字符串用户名{get { return (string)this["username"];}set { this["username"] = value;}}[ConfigurationProperty("SSHport", IsRequired = true, DefaultValue = 22)][IntegerValidator(MinValue = 1, MaxValue = 65536)]公共 int SSHPort{get { return (int)this["SSHport"];}set { this["SSHport"] = value;}}[ConfigurationProperty("password", IsRequired = false)]公共字符串密码{get { return (string)this["password"];}set { this["password"] = value;}}[ConfigurationProperty("privatekey", IsRequired = false)]公共字符串 私钥{得到{返回(字符串)这个[私钥"];}set { this["privatekey"] = value;}}[ConfigurationProperty("privatekeypassphrase", IsRequired = false)]公共字符串 Privatekeypassphrase{get { return (string)this["privatekeypassphrase"];}set { this["privatekeypassphrase"] = value;}}[ConfigurationProperty("tunnels", IsDefaultCollection = false)]公共隧道集合隧道{得到{返回(隧道集合)基[隧道"];}}}公共类 TunnelCollection : ConfigurationElementCollection{public new TunnelConfigElement this[字符串名称]{得到{如果 (IndexOf(name) <0) 返回空值;返回 (TunnelConfigElement)BaseGet(name);}}public TunnelConfigElement this[int index]{得到 { 返回 (TunnelConfigElement)BaseGet(index);}}public int IndexOf(字符串名称){name = name.ToLower();for (int idx = 0; idx 

和配置代码

 <配置><configSections><section name="TunnelSection" type="SSHTunnelWF.TunnelSection,SSHTunnelWF"/></configSections><隧道部分><host SSHServerHostname="tsg.edssdn.net" username="user" SSHport="22" password="pass" privatekey="" privatekeypassphrase=""><隧道><tunnel name="tfs" localport="8081" remoteport="8080" destinationserver="tfs2010.dev.com"/><tunnel name="sql" localport="14331" remoteport="1433" destinationserver="sql2008.dev.com"/><tunnel name="crm2011app" localport="81" remoteport="80" destinationserver="crm2011betaapp.dev.com"/></隧道></host><host SSHServerHostname="blade16" username="root" SSHport="22" password="pass" privatekey="" privatekeypassphrase=""><隧道><tunnel name="vnc" localport="5902" remoteport="5902" destinationserver="blade1.dev.com"/></隧道></host></隧道部分></配置>

然后是呼叫"

TunnelSection 隧道 = ConfigurationManager.GetSection("TunnelSection") as TunnelSection

In a web application, I want to be able to define some mapping using a config section like this:

<configuration>
    <configSections>
        <sectionGroup name="MyCustomer">
            <section name="CatalogMappings" type="MyCustom.MyConfigSection" />
        </sectionGroup>
    </configSections>
    <MyCustomer>
        <catalogMappings>
            <catalog name="toto">
                <mapping value="1" displayText="titi" />
                <mapping value="2" displayText="tata" />
            </catalog>
            <catalog name="toto2">
                <mapping value="1" displayText="titi2" />
                <mapping value="2" displayText="tata2" />
            </catalog>
        </catalogMappings>
    </MyCustomer>
</configuration>

I'm struggling to achieve this goal, especially when defining my collection of collections. What are the classes that I need to implement to achieve this?

Currently, I have:

public class CatalogMappingSection : System.Configuration.ConfigurationSection
{
    public class Mapping : ConfigurationElement
    {
        [ConfigurationProperty("externalKey")]
        public string ExternalKey { get; set; }
        [ConfigurationProperty("displayText", IsRequired=true)]
        public string DisplayText { get; set; }
        [ConfigurationProperty("value", IsRequired=true, IsKey=true)]
        public int Value { get; set; }
    }

    public class Catalog : ConfigurationElementCollection
    {
        [ConfigurationProperty("name", IsRequired=true, IsKey=true)]
        public string Name { get; set; }

        protected override ConfigurationElement CreateNewElement()
        {
            return new Mapping();
        }

        protected override object GetElementKey(ConfigurationElement element)
        {
            return ((Mapping)element).Value;
        }
    }

    public class CatalogCollection : ConfigurationElementCollection
    {
        [ConfigurationProperty("catalog")]
        [ConfigurationCollection(typeof(Catalog))]
        public Catalog CatalogMappingCollection
        {
            get
            {
                return (Catalog)base["catalog"];
            }
        }

        protected override ConfigurationElement CreateNewElement()
        {
            return new Catalog();
        }

        protected override object GetElementKey(ConfigurationElement element)
        {
            return ((Catalog)element).Name;
        }
    }

    [ConfigurationProperty("catalogMappings")]
    [ConfigurationCollection(typeof(CatalogCollection))]
    public CatalogCollection CatalogMappings
    {
        get
        {
            return (CatalogCollection)base["catalogMappings"];
        }
    }
}

But, this is not working as expected.

解决方案

I finally found this guy's example. It was coded and worked right out of the box.

http://manyrootsofallevilrants.blogspot.com/2011/07/nested-custom-configuration-collections.html

I am going to paste the code here......only because I cannot stand it when someone says "Your answer is here", and the link is dead.

Please try his website first, and leave a "thank you" if it works.

using System;
using System.Configuration;

namespace SSHTunnelWF
{
    public class TunnelSection : ConfigurationSection
    {
        [ConfigurationProperty("", IsDefaultCollection = true)]  
        public HostCollection Tunnels
        {
            get
            {
                HostCollection hostCollection = (HostCollection)base[""];
                return hostCollection;                
            }
        }
    }

    public class HostCollection : ConfigurationElementCollection
    {
        public HostCollection()
        {
            HostConfigElement details = (HostConfigElement)CreateNewElement();
            if (details.SSHServerHostname != "")
            {
                Add(details);
            }
        }

        public override ConfigurationElementCollectionType CollectionType
        {
            get
            {
                return ConfigurationElementCollectionType.BasicMap;
            }
        }

        protected override ConfigurationElement CreateNewElement()
        {
            return new HostConfigElement();
        }

        protected override Object GetElementKey(ConfigurationElement element)
        {
            return ((HostConfigElement)element).SSHServerHostname;
        }

        public HostConfigElement this[int index]
        {
            get
            {
                return (HostConfigElement)BaseGet(index);
            }
            set
            {
                if (BaseGet(index) != null)
                {
                    BaseRemoveAt(index);
                }
                BaseAdd(index, value);
            }
        }

        new public HostConfigElement this[string name]
        {
            get
            {
                return (HostConfigElement)BaseGet(name);
            }
        }

        public int IndexOf(HostConfigElement details)
        {
            return BaseIndexOf(details);
        }

        public void Add(HostConfigElement details)
        {
            BaseAdd(details);
        }

        protected override void BaseAdd(ConfigurationElement element)
        {
            BaseAdd(element, false);
        }

        public void Remove(HostConfigElement details)
        {
            if (BaseIndexOf(details) >= 0)
                BaseRemove(details.SSHServerHostname);
        }

        public void RemoveAt(int index)
        {
            BaseRemoveAt(index);
        }

        public void Remove(string name)
        {
            BaseRemove(name);
        }

        public void Clear()
        {
            BaseClear();
        }

        protected override string ElementName
        {
            get { return "host"; }
        }
    }

    public class HostConfigElement:ConfigurationElement
    {
        [ConfigurationProperty("SSHServerHostname", IsRequired = true, IsKey = true)]
        [StringValidator(InvalidCharacters = "  ~!@#$%^&*()[]{}/;’"|\")]
        public string SSHServerHostname
        {
            get { return (string)this["SSHServerHostname"]; }
            set { this["SSHServerHostname"] = value; }
        }

        [ConfigurationProperty("username", IsRequired = true)]
        [StringValidator(InvalidCharacters = "  ~!@#$%^&*()[]{}/;’"|\")]
        public string Username
        {
            get { return (string)this["username"]; }
            set { this["username"] = value; }
        }

        [ConfigurationProperty("SSHport", IsRequired = true, DefaultValue = 22)]
        [IntegerValidator(MinValue = 1, MaxValue = 65536)]
        public int SSHPort
        {
            get { return (int)this["SSHport"]; }
            set { this["SSHport"] = value; }
        }

        [ConfigurationProperty("password", IsRequired = false)]
        public string Password
        {
            get { return (string)this["password"]; }
            set { this["password"] = value; }
        }

        [ConfigurationProperty("privatekey", IsRequired = false)]
        public string Privatekey
        {
            get { return (string)this["privatekey"]; }
            set { this["privatekey"] = value; }
        }

        [ConfigurationProperty("privatekeypassphrase", IsRequired = false)]
        public string Privatekeypassphrase
        {
            get { return (string)this["privatekeypassphrase"]; }
            set { this["privatekeypassphrase"] = value; }
        }

        [ConfigurationProperty("tunnels", IsDefaultCollection = false)]
        public TunnelCollection Tunnels
        {
            get { return (TunnelCollection)base["tunnels"]; }
        }
    }

    public class TunnelCollection : ConfigurationElementCollection
    {
        public new TunnelConfigElement this[string name]
        {
            get
            {
                if (IndexOf(name) < 0) return null;
                return (TunnelConfigElement)BaseGet(name);
            }
        }

        public TunnelConfigElement this[int index]
        {
            get { return (TunnelConfigElement)BaseGet(index); }
        }

        public int IndexOf(string name)
        {
            name = name.ToLower();

            for (int idx = 0; idx < base.Count; idx++)
            {
                if (this[idx].Name.ToLower() == name)
                    return idx;
            }
            return -1;
        }

        public override ConfigurationElementCollectionType CollectionType
        {
            get { return ConfigurationElementCollectionType.BasicMap; }
        }

        protected override ConfigurationElement CreateNewElement()
        {
            return new TunnelConfigElement();
        }

        protected override object GetElementKey(ConfigurationElement element)
        {
            return ((TunnelConfigElement)element).Name;
        }

        protected override string ElementName
        {
            get { return "tunnel"; }
        }
    }

    public class TunnelConfigElement : ConfigurationElement
    {        
        public TunnelConfigElement()
        {
        }

        public TunnelConfigElement(string name, int localport, int remoteport, string destinationserver)
        {
            this.DestinationServer = destinationserver;
            this.RemotePort = remoteport;
            this.LocalPort = localport;            
            this.Name = name;
        }

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

        [ConfigurationProperty("localport", IsRequired = true, DefaultValue =1)]
        [IntegerValidator(MinValue = 1, MaxValue = 65536)]
        public int LocalPort
        {
            get { return (int)this["localport"]; }
            set { this["localport"] = value; }
        }

        [ConfigurationProperty("remoteport", IsRequired = true, DefaultValue =1)]
        [IntegerValidator(MinValue = 1, MaxValue = 65536)]
        public int RemotePort
        {
            get { return (int)this["remoteport"]; }
            set { this["remoteport"] = value; }
        }

        [ConfigurationProperty("destinationserver", IsRequired = true)]
        [StringValidator(InvalidCharacters = "  ~!@#$%^&*()[]{}/;’"|\")]
        public string DestinationServer
        {
            get { return (string)this["destinationserver"]; }
            set { this["destinationserver"] = value; }
        }
    }
}

And the configuration code

 <?xml version="1.0"?>
 <configuration>
   <configSections>
     <section name="TunnelSection" type="SSHTunnelWF.TunnelSection,SSHTunnelWF" />
   </configSections>
   <TunnelSection>
     <host SSHServerHostname="tsg.edssdn.net" username="user" SSHport="22" password="pass" privatekey="" privatekeypassphrase="">
       <tunnels>
         <tunnel name="tfs" localport="8081"  remoteport="8080" destinationserver="tfs2010.dev.com"  />
         <tunnel name="sql" localport="14331"  remoteport="1433" destinationserver="sql2008.dev.com"  />
         <tunnel name="crm2011app" localport="81"  remoteport="80" destinationserver="crm2011betaapp.dev.com"  />
       </tunnels>
     </host>
     <host SSHServerHostname="blade16" username="root" SSHport="22"  password="pass" privatekey="" privatekeypassphrase="">
      <tunnels>
        <tunnel name="vnc" localport="5902"  remoteport="5902" destinationserver="blade1.dev.com" />
      </tunnels>
     </host>
   </TunnelSection>
 </configuration>

And then the "call"

TunnelSection tunnels = ConfigurationManager.GetSection("TunnelSection") as TunnelSection

这篇关于使用嵌套集合正确实现自定义配置部分?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆