2009-02-03 27 views
8

假设我在ASP.NET web.config中定义配置部分,如:是否可以在自定义配置节中拥有任意的XML?

<?xml version="1.0"?> 
<configuration> 
    <configSections> 
    <sectionGroup name="system.web"> 
     <section name="MySettings" type="MyCompany.MyProject.Configuration.MySettings" allowLocation="true" allowDefinition="Everywhere" restartOnExternalChanges="false" /> 
    </sectionGroup> 
    </configSections> 
    <system.web> 
    <MySettings knownProperty="some_value" unknownProperty="other_value" /> 
    </system.web> 
</configuration> 

并假设我定义MySettings : System.Configuration.ConfigurationSection没有unknownProperty

using System.Configuration; 

namespace MyCompany.MyProject.Configuration 
{ 
    public class MySettings : ConfigurationSection 
    { 
     public MySettings() { } 

     [ConfigurationProperty("knownProperty", DefaultValue="default_value")] 
     public string KnownProperty 
     { 
     get { return (string)this["knownProperty"]; } 
     } 

     // I'm not defining unknownProperty here on purpose 
    } 
} 

反正是有运行应用程序,而不抱怨无法识别的属性“unknownProperty”的配置错误?

此外,我会很好的方式来捕捉错误,如果可能的话忽略它。

换句话说,我希望XML具有未绑定到的匹配类型中定义的属性。它可以在现有配置API的范围内完成吗?

回答

6

我敢肯定,这是可能的,因为一些内置的部分,如WCF和成员资格,这样做没有错误。 OnDeserializeUnrecognizedAttribute做你需要的吗?

protected override bool OnDeserializeUnrecognizedAttribute(string name, string value){ 
//don't call base to avoid error 
} 
2

我正在使用下面的代码从我的web.config ASP文件中成功读取任何XML结构。请注意,只支持读取。

using System; 
using System.Collections.Generic; 
using System.Text; 
using System.Configuration; 
using System.Xml; 

/* In this file, you'll find an example on how to store an custom section in an .Net 
* application configuration file that can contains arbitrary XML that can be retrieved 
* as a raw System.Xml.XmlNode. In the specific example below, I wanted to be able to 
* store arbitrary information about POP servers I retrieve email from, without having to 
* write specific Configuration data for each different case. This is usefull for quick 
* application development. 
*/ 

/* Config file sample : 
<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <configSections> 
     <sectionGroup name="MySection"> 
      <section name="MailRetrieve" type="ConsoleApplication1.MailRetrieveConfigurationSection, ConsoleApplication1"/> 
     </sectionGroup> 
    </configSections> 


    <MySection> 
     <MailRetrieve> 
      <Hosts> 
       <add username="[email protected]" popserver="mail.domain.com" password="1234"> 
        <RawXml> 
         <AnElement>Arbitrary string one</AnElement> 
        </RawXml> 
       </add> 
       <add username="[email protected]" popserver="mail.domain.com" password="1234"></add> 
       <add username="[email protected]" popserver="mail.domain.com" password="1234" > 
        <RawXml> 
         <OtherElement>Arbitrary string two</OtherElement> 
        </RawXml> 
       </add> 
      </Hosts> 
     </MailRetrieve> 
    </MySection> 
    </configuration> 
*/ 

/* Sample output : running the piece of code below, using config file above, gives : 

     Custom XML for [email protected][email protected]__mail.domain.com: 
     <RawXml><AnElement>Arbitrary string one</AnElement></RawXml> 
     ************ 
     Custom XML for [email protected][email protected]__mail.domain.com: 
     - none - 
     ************ 
     Custom XML for [email protected][email protected]__mail.domain.com: 
     <RawXml><OtherElement>Arbitrary string two</OtherElement></RawXml> 
     --> Found OtherElement ! 
     ************ 
     Hit a key to finish 

*/ 

namespace ConsoleApplication1 { 
    class Program { 
     static void Main(string[] args) { 

      MailRetrieveConfigurationSection config = (MailRetrieveConfigurationSection) 
        (System.Configuration.ConfigurationManager.GetSection("MySection/MailRetrieve")); 


      if (config != null) { 
       foreach (HostConfigElement cfg in config.Hosts) { 
        System.Console.WriteLine("Custom XML for " + cfg.PopMailboxID + ":"); 
        if (cfg.RawXml.Node != null) { 
         System.Console.WriteLine(cfg.RawXml.Node.OuterXml); 
         if (cfg.RawXml.Node.SelectSingleNode("OtherElement") != null) { 
          Console.WriteLine("--> Found OtherElement !"); 
         } 
        } 
        else { 
         System.Console.WriteLine(" - none -"); 
        } 
        System.Console.WriteLine("************");      
       } 
      } 
      System.Console.WriteLine("Hit a key to finish"); 
      System.Console.ReadKey(); 
     } 
    } 


    public class MailRetrieveConfigurationSection : ConfigurationSection { 
     [ConfigurationProperty("Hosts")] 
     public MailRetrieveHostsConfigCollection Hosts { 
      get { 
       return ((MailRetrieveHostsConfigCollection)(base["Hosts"])); 
      } 
     } 
    } 

    [ConfigurationCollectionAttribute(typeof(HostConfigElement))] 
    public class MailRetrieveHostsConfigCollection : ConfigurationElementCollection { 
     protected override ConfigurationElement CreateNewElement() { 
      return new HostConfigElement(); 
     } 

     /// <summary> 
     /// We want to have only one configuration per POP mailbox, wich key is host+username 
     /// If more configuration is wanted, one must introduce an "id" attribute. 
     /// </summary>   
     protected override object GetElementKey(ConfigurationElement element) { 
      return ((HostConfigElement)(element)).PopMailboxID; 
     } 

     public void Add(HostConfigElement element) { 
      this.BaseAdd(element); 
     } 

     public void Remove(string key) { 
      this.BaseRemove(key); 
     } 

     public void Clear() { 
      this.BaseClear(); 
     } 


     public HostConfigElement this[int idx] { 
      get { return (HostConfigElement)this[idx]; } 
     } 
    } 


    public class MyCustomConfigurationElement : ConfigurationElement { 

     public XmlNode Node = null; 

     protected override void DeserializeElement(XmlReader reader, bool serializeCollectionKey) {      
      XmlDocument doc = new XmlDocument(); 
      doc.Load(reader.ReadSubtree()); 
      Node = doc.FirstChild; 
     }   
    } 

    public class HostConfigElement : ConfigurationElement { 

     /// <summary> 
     /// A POP3 mailbox is distinguished from another using the server name and user name. 
     /// </summary> 
     public string PopMailboxID { 
      get { 
       return Username + "[email protected]__" + PopServer; // 
      } 
     } 


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

     [ConfigurationProperty("username", IsRequired = true, Options = ConfigurationPropertyOptions.IsKey)] 
     public string Username { 
      get { return (string)this["username"]; } 
      set { this["username"] = value; } 
     } 

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


     [ConfigurationProperty("RawXml", IsRequired=false)] 
     public MyCustomConfigurationElement RawXml { 
      get { return (MyCustomConfigurationElement)this["RawXml"]; } 
      set { this["RawXml"] = value; } 
     } 


    } 
} 
1

从丹尼尔的回答继: -

protected override bool OnDeserializeUnrecognizedAttribute(string name, string value) { 
    try { 
     var lProperty = new ConfigurationProperty(name, typeof(String)); 
     Properties.Add(lProperty); 
     base[name] = value; 
     return true; 
    } catch { 
     return false; 
    } 
} 
相关问题