在我自己的自定义 appSettings 上使用 foreach 所需的代码
Posted
技术标签:
【中文标题】在我自己的自定义 appSettings 上使用 foreach 所需的代码【英文标题】:Code required to use foreach on my own custom appSettings 【发布时间】:2011-02-03 20:05:23 【问题描述】:我已经搜索了该网站,但没有找到我正在寻找的确切内容。关闭,但没有雪茄。
基本上我想要一个这样的配置部分:
<configSections>
<section name="PhoneNotificationsSection" type="Alerts.PhoneAlertConfigSection,Alerts,Version=1.0.0.0,Culture=neutral,PublicKeyToken=null"/>
</configSections>
<PhoneNotificationsSection>
<phones>
<add phone="MyMobile" value="1234567890@vtext.com" />
<add phone="OtherMobile" value="1234567890@txt.att.com" />
</phones>
</PhoneNotificationsSection>
然后我想,在我的 appSettings 消费代码中,能够编写这样的东西(伪代码):
foreach (phone p in phones)
//'phone' attribute is just helpful/descriptive
DoSomething(p.value);
我已经做了足够多的研究,知道我可能需要一些我自己的类来实现和/或继承自某些配置类,以使上述代码成为可能。我只是没有找到任何可以清楚地展示这种情况以及如何为它编写代码的东西——当我尝试了解整个 .NET 配置世界时,我的大脑开始受到伤害。任何人都可以分享一些我正在寻找的代码吗?
【问题讨论】:
【参考方案1】:我曾经写过类似的东西,作为 C# 课程的示例。在我看来,它主要展示了 .NET 配置子系统是多么糟糕,尽管代码确实有效。我没有根据您的设置对其进行调整,因为很容易引入错误,并且到目前为止 SO 编辑器不验证发布的代码示例;)
一、配置节声明:
<configSections>
<section name="passwordSafe"
type="Codeworks.PasswordSafe.Model.Configuration.PasswordSafeSection, Codeworks.PasswordSafe.Model, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
</configSections>
<passwordSafe hashAlgorithm="SHA256">
<users>
<user name="mm" password="Jok2eyBcFs4y7UIAlCuLix4mLfxw2byfvHfElpmk8d8=" />
<user name="joe" password="Jok2eyBcFs4y7UIAlCuLix4mLfxw2byfvHfElpmk8d8=" />
</users>
</passwordSafe>
为了匹配上面的 sn-p 我们首先需要配置部分:
public class PasswordSafeSection : ConfigurationSection
#region Static Accessors
/// <summary>
/// Gets the configuration section using the default element name.
/// </summary>
public static PasswordSafeSection GetSection()
return GetSection( "passwordSafe" );
/// <summary>
/// Gets the configuration section using the specified element name.
/// </summary>
public static PasswordSafeSection GetSection( string sectionName )
PasswordSafeSection section = ConfigurationManager.GetSection( sectionName ) as PasswordSafeSection;
if( section == null )
string message = string.Format( "The specified configuration section (<0>) was not found.", sectionName );
throw new ConfigurationErrorsException( message );
return section;
#endregion
#region Configuration Properties
[ConfigurationProperty( "hashAlgorithm" )]
public string HashAlgorithm
get return (string) this[ "hashAlgorithm" ];
set this[ "hashAlgorithm" ] = value;
[ConfigurationProperty( "users", IsDefaultCollection=true )]
public UserElementCollection Users
get return (UserElementCollection) this[ "users" ];
set this[ "users" ] = value;
public override bool IsReadOnly()
return false;
#endregion
我们正在使用自定义元素集合,所以我们也声明一下:
[ConfigurationCollection( typeof(UserElement), CollectionType = ConfigurationElementCollectionType.BasicMap )]
public class UserElementCollection : ConfigurationElementCollection
protected override ConfigurationElement CreateNewElement()
return new UserElement();
protected override string ElementName
get return "user";
public override ConfigurationElementCollectionType CollectionType
get return ConfigurationElementCollectionType.BasicMap;
public override bool IsReadOnly()
return false;
#region Indexers
public UserElement this[ int index ]
get return BaseGet( index ) as UserElement;
set
if( BaseGet( index ) != null )
BaseRemoveAt( index );
BaseAdd( index, value );
public new UserElement this[ string name ]
get return BaseGet( name ) as UserElement;
#endregion
#region Lookup Methods
protected override object GetElementKey( ConfigurationElement element )
UserElement user = element as UserElement;
return user != null ? user.UserName : "error";
public string GetKey( int index )
return (string) BaseGetKey( index );
#endregion
#region Add/Remove/Clear Methods
public void Add( UserElement item )
BaseAdd( item );
public void Remove( string name )
BaseRemove( name );
public void Remove( UserElement item )
BaseRemove( GetElementKey( item ) );
public void RemoveAt( int index )
BaseRemoveAt( index );
public void Clear()
BaseClear();
#endregion
最后我们需要声明元素集合中使用的自定义元素:
public class UserElement : ConfigurationElement
#region Constructors
public UserElement()
public UserElement( string userName, string passwordHash )
UserName = userName;
PasswordHash = passwordHash;
#endregion
#region Configuration Properties
[ConfigurationProperty( "name", IsKey = true )]
public string UserName
get return (string) this[ "name" ];
set this[ "name" ] = value;
[ConfigurationProperty( "password", IsRequired = true )]
public string PasswordHash
get return (string) this[ "password" ];
set this[ "password" ] = value;
public override bool IsReadOnly()
return false;
#endregion
现在,一切就绪,我们就可以访问配置文件了。我正在使用一个 Configurator 帮助类来简化这个过程:
public static class Configurator
#region AppSettings Helpers
public static int SplashScreenDisplayTime
get return Convert.ToInt32( ConfigurationManager.AppSettings[ "splash.display.msecs" ] );
#endregion
#region User Helpers
public static bool TryGetUserPasswordHash( string userName, out string passwordHash )
UserElement user = GetUser( userName );
passwordHash = user != null ? user.PasswordHash : null;
return ! string.IsNullOrEmpty( passwordHash );
private static UserElement GetUser( string userName )
SystemConfiguration config = GetConfiguration( ConfigurationUserLevel.PerUserRoamingAndLocal );
PasswordSafeSection section = config.Sections[ "passwordSafe" ] as PasswordSafeSection;
return section.Users[ userName ];
public static void AddUser( string userName, string passwordHash, string encryptionKey )
SystemConfiguration config = GetConfiguration( ConfigurationUserLevel.PerUserRoamingAndLocal );
PasswordSafeSection section = config.Sections[ "passwordSafe" ] as PasswordSafeSection;
UserElement user = section.Users[ userName ];
if( user == null )
user = new UserElement( userName, passwordHash, encryptionKey );
section.Users.Add( user );
config.Save( ConfigurationSaveMode.Modified );
public static void RemoveUser( string userName )
SystemConfiguration config = GetConfiguration( ConfigurationUserLevel.PerUserRoamingAndLocal );
PasswordSafeSection section = config.Sections[ "passwordSafe" ] as PasswordSafeSection;
section.Users.Remove( userName );
config.Save( ConfigurationSaveMode.Modified );
public static void UpdateUser( string userName, string passwordHash )
SystemConfiguration config = GetConfiguration( ConfigurationUserLevel.PerUserRoamingAndLocal );
PasswordSafeSection section = config.Sections[ "passwordSafe" ] as PasswordSafeSection;
UserElement user = section.Users[ userName ];
if( user != null )
user.PasswordHash = passwordHash;
config.Save( ConfigurationSaveMode.Modified );
#endregion
#region Configuration Helpers
private static SystemConfiguration GetConfiguration( ConfigurationUserLevel userLevel )
SystemConfiguration config = InitializeConfiguration( userLevel );
return config;
private static SystemConfiguration InitializeConfiguration( ConfigurationUserLevel userLevel )
SystemConfiguration config = ConfigurationManager.OpenExeConfiguration( userLevel );
PasswordSafeSection section = config.Sections[ "passwordSafe" ] as PasswordSafeSection;
if( section == null )
section = new PasswordSafeSection();
section.SectionInformation.AllowExeDefinition = ConfigurationAllowExeDefinition.MachineToLocalUser;
section.SectionInformation.ForceSave = true;
config.Sections.Add( "passwordSafe", section );
config.Save( ConfigurationSaveMode.Full );
return config;
#endregion
希望这会有所帮助。
【讨论】:
无法编译此代码 - 最后一个代码 sn-p 中返回“SystemConfiguration”对象的最后 2 个方法 - 编译器无法识别 SystemConfiguration 类并认为我缺少程序集参考。该类在哪里定义?我需要特定的“使用”声明吗? 另外 - 你能告诉我你如何使用这个代码来访问SystemConfiguration
的类型是什么?以上是关于在我自己的自定义 appSettings 上使用 foreach 所需的代码的主要内容,如果未能解决你的问题,请参考以下文章
如何在我自己的自定义视图中重现 iPhone UIScrollView 的轻弹滚动行为?