假设我在ASP.NET web.config中定义了一个配置部分,如:
<?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具有一个未在其绑定的匹配类型中定义的属性。可以在现有Configuration API的范围内完成吗?
答案 0 :(得分:7)
我很确定这是可能的,因为一些内置的部分,如WCF和成员资格,这样做没有错误。 OnDeserializeUnrecognizedAttribute是否满足您的需求?
protected override bool OnDeserializeUnrecognizedAttribute(string name, string value){
//don't call base to avoid error
}
答案 1 :(得分: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="projects@domain.com" popserver="mail.domain.com" password="1234">
<RawXml>
<AnElement>Arbitrary string one</AnElement>
</RawXml>
</add>
<add username="tasks@domain.com" popserver="mail.domain.com" password="1234"></add>
<add username="bugs@domain.com" 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 projects@domain.com__@__mail.domain.com:
<RawXml><AnElement>Arbitrary string one</AnElement></RawXml>
************
Custom XML for tasks@domain.com__@__mail.domain.com:
- none -
************
Custom XML for bugs@domain.com__@__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 + "__@__" + 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; }
}
}
}
答案 2 :(得分:2)
继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;
}
}
答案 3 :(得分:0)
这是我最后得到的最少的代码示例:
auto
在这里获取xml元素
public class XmlConfigurationSection : ConfigurationSection
{
[ConfigurationProperty("xml", IsRequired = false)]
public XmlElement Xml
{
get { return (XmlElement)this["xml"]; }
set { this["xml"] = value; }
}
}
public class XmlElement : ConfigurationElement
{
public XmlNode Node = null;
protected override void DeserializeElement(XmlReader reader, bool serializeCollectionKey)
{
XmlDocument doc = new XmlDocument();
doc.Load(reader.ReadSubtree());
Node = doc.FirstChild;
}
}
WebConfig 设置如下:
var xml = (System.Configuration.ConfigurationManager.GetSection("xmlSettings") as XmlConfigurationSection).Xml;