C# 如何检查appSettings密钥是否存在?

C# 如何检查appSettings密钥是否存在?,c#,appsettings,configurationmanager,C#,Appsettings,Configurationmanager,如何检查应用程序设置是否可用 i、 e.app.config <?xml version="1.0" encoding="utf-8" ?> <configuration> <appSettings> <add key ="someKey" value="someValue"/> </appSettings> </configuration> 或 如果您要查找的键在配置文件中不存在,您将无法使用.ToSt

如何检查应用程序设置是否可用

i、 e.app.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings>
    <add key ="someKey" value="someValue"/>
  </appSettings>
</configuration>


如果您要查找的键在配置文件中不存在,您将无法使用.ToString()将其转换为字符串,因为该值将为null,并且您将收到“对象引用未设置为对象实例”错误。在尝试获取字符串表示形式之前,最好先查看该值是否存在

if (!String.IsNullOrEmpty(ConfigurationManager.AppSettings["myKey"]))
{
    String myKey = ConfigurationManager.AppSettings["myKey"].ToString();
}
或者,正如代码猴子所建议的:

if (ConfigurationSettings.AppSettings["myKey"] != null)
{
// Now do your magic..
}

上面的选项为所有方式提供了灵活性,如果您知道键类型,请尝试解析它们
bool.TryParse(ConfigurationManager.AppSettings[“myKey”],out myvariable)

我认为LINQ表达式可能是最好的:

   const string MyKey = "myKey"

   if (ConfigurationManager.AppSettings.AllKeys.Any(key => key == MyKey))
          {
              // Key exists
          }

通过泛型和LINQ安全地返回默认值

public T ReadAppSetting<T>(string searchKey, T defaultValue, StringComparison compare = StringComparison.Ordinal)
{
    if (ConfigurationManager.AppSettings.AllKeys.Any(key => string.Compare(key, searchKey, compare) == 0)) {
        try
        { // see if it can be converted.
            var converter = TypeDescriptor.GetConverter(typeof(T));
            if (converter != null) defaultValue = (T)converter.ConvertFromString(ConfigurationManager.AppSettings.GetValues(searchKey).First());
        }
        catch { } // nothing to do just return the defaultValue
    }
    return defaultValue;
}
我喜欢,但需要它在C++/CLI中工作。这就是我的结局。没有LINQ的用法,但是很有效

generic <typename T> T MyClass::ReadAppSetting(String^ searchKey, T defaultValue) {
  for each (String^ setting in ConfigurationManager::AppSettings->AllKeys) {
    if (setting->Equals(searchKey)) { //  if the key is in the app.config
      try {                           // see if it can be converted
        auto converter = TypeDescriptor::GetConverter((Type^)(T::typeid)); 
        if (converter != nullptr) { return (T)converter->ConvertFromString(ConfigurationManager::AppSettings[searchKey]); }
      } catch (Exception^ ex) {} // nothing to do
    }
  }
  return defaultValue;
}
generic T MyClass::ReadAppSetting(字符串^searchKey,T defaultValue){
对于每个(ConfigurationManager::AppSettings->AllKeys中的字符串^setting){
如果(设置->等于(搜索键)){//如果键在app.config中
试试{//看看它是否可以转换
自动转换器=TypeDescriptor::GetConverter((Type^)(T::typeid));
if(converter!=nullptr){return(T)converter->ConvertFromString(ConfigurationManager::AppSettings[searchKey]);}
}catch(异常^ex){}//无事可做
}
}
返回默认值;
}
在TryParse中使用新的c#语法对我来说效果很好:

  // TimeOut
  if (int.TryParse(ConfigurationManager.AppSettings["timeOut"], out int timeOut))
  {
     this.timeOut = timeOut;
  }

我们的库中有一个可以方便地检索设置的函数:
Dim configValue As String=Util.IsNull(ConfigurationManager.AppSettings.Get(“SettingName”)、String.Empty)
它抛出“对象引用未设置为对象的实例”,如果您检查IsNullOrEmpty,则“键”的逻辑不存在”将在您实际拥有一个具有空字符串值的键作为有效设置时运行。这不是最佳答案,因为这会引发异常。DivyeshPatel是一个更好的解决方案。如果不使用.NET4.5抛出异常。如果我的设置存在,但包含空值或空值,则返回假阳性。应该有一个
HasKey()
或类似的方法。Divyesh Patel提供的答案更为正确。如果您不想在事后使用该值,这可能会稍微更有效(?)。问题特别提到测试“应用程序设置是否可用”。由于可用性意味着我想使用它,我想说user195488提供的答案对来这里的人更有用——但严格来说,你的答案也是正确的。这是一个更好的解决方案,因为它实际上是在检查密钥是否存在。如果我的密钥值为空,则user195488提供的解决方案将给我一个假阳性。此解决方案不正确。AppSettings是一个NameValueCollection,在查询键时默认不区分大小写。您在这里使用的LINQ.Contains扩展方法将默认为区分大小写的比较。当然。。。但是idunno——这种方法有什么好处吗?如果我真的精通Linq(大多数C#程序员最终可能会精通Linq),那么阅读这个示例可能会很容易,但我认为这不会更容易——所以除非有效率优势。。。为什么?没有效率优势,而且语法冗长。
ConfigurationManager。AppSettings
不区分大小写,
Any(key=>key==MyKey
但是
ConfigurationManager。AppSettings
不区分大小写,
Any(key=>key==MyKey
但是is@janv8000我想要区分大小写,但更新了示例以处理它。使用ToUpper进行正确的不区分大小写比较更快(请参阅)。更可取的做法是使用string.Equals()重载传递StringComparisonType。这是一个非常好的解决方案。我对实现进行了一些修改,以支持所需设置的概念。只需一件事-记住使用System.ComponentModel;
语句向类添加
,以支持使用
TypeDescriptor
类。欢迎使用SO!当y如果你给出了答案,请试着解释一下你的解决方案。在这种情况下,还有一些答案,试着揭露你的优点。
   const string MyKey = "myKey"

   if (ConfigurationManager.AppSettings.AllKeys.Any(key => key == MyKey))
          {
              // Key exists
          }
var isAlaCarte = 
    ConfigurationManager.AppSettings.AllKeys.Contains("IsALaCarte") && 
    bool.Parse(ConfigurationManager.AppSettings.Get("IsALaCarte"));
public T ReadAppSetting<T>(string searchKey, T defaultValue, StringComparison compare = StringComparison.Ordinal)
{
    if (ConfigurationManager.AppSettings.AllKeys.Any(key => string.Compare(key, searchKey, compare) == 0)) {
        try
        { // see if it can be converted.
            var converter = TypeDescriptor.GetConverter(typeof(T));
            if (converter != null) defaultValue = (T)converter.ConvertFromString(ConfigurationManager.AppSettings.GetValues(searchKey).First());
        }
        catch { } // nothing to do just return the defaultValue
    }
    return defaultValue;
}
string LogFileName = ReadAppSetting("LogFile","LogFile");
double DefaultWidth = ReadAppSetting("Width",1280.0);
double DefaultHeight = ReadAppSetting("Height",1024.0);
Color DefaultColor = ReadAppSetting("Color",Colors.Black);
generic <typename T> T MyClass::ReadAppSetting(String^ searchKey, T defaultValue) {
  for each (String^ setting in ConfigurationManager::AppSettings->AllKeys) {
    if (setting->Equals(searchKey)) { //  if the key is in the app.config
      try {                           // see if it can be converted
        auto converter = TypeDescriptor::GetConverter((Type^)(T::typeid)); 
        if (converter != nullptr) { return (T)converter->ConvertFromString(ConfigurationManager::AppSettings[searchKey]); }
      } catch (Exception^ ex) {} // nothing to do
    }
  }
  return defaultValue;
}
  // TimeOut
  if (int.TryParse(ConfigurationManager.AppSettings["timeOut"], out int timeOut))
  {
     this.timeOut = timeOut;
  }