2009-02-03 32 views
8

Giả sử tôi xác định một phần cấu hình trong một web.config ASP.NET như:Có thể có XML tùy ý trong phần cấu hình tùy chỉnh không?

<?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> 

Và giả sử tôi xác định MySettings : System.Configuration.ConfigurationSectionmà khôngunknownProperty:

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

Có anyway để chạy các ứng dụng mà không nhận được Lỗi cấu hình phàn nàn về thuộc tính không xác định 'unknownProperty'?

Tôi cũng sẽ ổn với cách để bắt lỗi đó và bỏ qua nếu có thể.

Nói cách khác, tôi muốn XML có thuộc tính không được xác định trong loại so khớp mà nó bị ràng buộc. Nó có thể được thực hiện trong giới hạn của API cấu hình hiện tại không?

Trả lời

6

Tôi khá chắc chắn điều đó là có thể, vì một số phần được tích hợp sẵn, như WCF và tư cách thành viên, làm điều này không có lỗi. OnDeserializeUnrecognizedAttribute có làm những gì bạn cần không?

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

Tôi đang sử dụng mã bên dưới để đọc thành công mọi cấu trúc XML từ tệp web.config ASP của mình. Lưu ý rằng chỉ đọc được hỗ trợ.

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

Tiếp theo từ câu trả lời của Daniel: -

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; 
    } 
} 
Các vấn đề liên quan