Làm cách nào để kiểm tra xem khóa ứng dụng có tồn tại không?


146

Làm cách nào để kiểm tra xem Cài đặt ứng dụng có khả dụng không?

tức là app.config

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

và trong bộ mã

if (ConfigurationManager.AppSettings.ContainsKey("someKey"))
{
  // Do Something
}else{
  // Do Something Else
}

Câu trả lời:


223

MSDN: Trình quản lý cấu hình. Cài đặt

if (ConfigurationManager.AppSettings[name] != null)
{
// Now do your magic..
}

hoặc là

string s = ConfigurationManager.AppSettings["myKey"];
if (!String.IsNullOrEmpty(s))
{
    // Key exists
}
else
{
    // Key doesn't exist
}

2
Chúng tôi có một hàm IsNull giống như SQL trong thư viện của chúng tôi, giúp truy xuất một cài đặt rất tiện dụng:Dim configValue As String = Util.IsNull(ConfigurationManager.AppSettings.Get("SettingName"), String.Empty)
Eirik H

10
Nó ném "Tham chiếu đối tượng không được đặt thành phiên bản của đối tượng"
Waqar Alamgir

Không, nó sai. Nếu "myKey" không tồn tại trong nút xml cài đặt ứng dụng, mã sẽ ném ngoại lệ.
Gionata

nếu bạn kiểm tra IsNullOrEmpty thì logic của bạn cho "khóa không tồn tại" sẽ chạy khi bạn thực sự có một khóa có giá trị chuỗi trống dưới dạng cài đặt hợp lệ
nrjohnstone 7/07/2016

3
không phải là câu trả lời tốt nhất vì điều này ném ngoại lệ. Divyesh Patel là một giải pháp tốt hơn.
VRPF

81
if (ConfigurationManager.AppSettings.AllKeys.Contains("myKey"))
{
    // Key exists
}
else
{
    // Key doesn't exist
}

Điều này có thể sẽ hiệu quả hơn một chút (?) Nếu bạn không muốn sử dụng giá trị sau đó. Câu hỏi đề cập cụ thể đến việc kiểm tra 'nếu Cài đặt ứng dụng khả dụng'. Vì Sẵn có ngụ ý muốn sử dụng nó trong tâm trí của tôi, tôi nói rằng câu trả lời được cung cấp bởi người dùng 195488 sẽ hữu ích hơn cho những người đến đây - nhưng nói đúng ra, câu trả lời của bạn cũng đúng.

10
Đây là một giải pháp tốt hơn nhiều cho thực tế đơn giản là nó thực sự đang kiểm tra nếu khóa tồn tại. Nếu tôi có giá trị trống cho khóa của mình, giải pháp được cung cấp bởi người dùng 195488 sẽ cho tôi kết quả dương tính giả.
chứng khó đọc

6
Giải pháp này không chính xác. AppSinstall là NameValueCollection, theo mặc định là không phân biệt chữ hoa chữ thường khi nói đến tra cứu khóa. Phương thức mở rộng LINQ .Contains bạn đang sử dụng ở đây tuy nhiên sẽ mặc định là so sánh phân biệt chữ hoa chữ thường .
Jax

9

Trả về giá trị mặc định một cách an toàn thông qua thuốc generic và 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 sử dụng như sau:

string LogFileName = ReadAppSetting("LogFile","LogFile");
double DefaultWidth = ReadAppSetting("Width",1280.0);
double DefaultHeight = ReadAppSetting("Height",1024.0);
Color DefaultColor = ReadAppSetting("Color",Colors.Black);

ConfigurationManager.AppSettingsAny(key => key == MyKeytuy nhiên không phân biệt chữ hoa chữ thường
janv8000

@ janv8000 Tôi muốn phân biệt chữ hoa chữ thường, nhưng đã cập nhật ví dụ để xử lý nó.
viết mã

Các so sánh không phân biệt chữ hoa chữ thường đúng nhanh hơn với ToUpper (xem stackoverflow.com/a/12137/389424 ). Ngay cả beter cũng sử dụng quá tải chuỗi.Equals () khi truyền StringComparisonType.
janv8000

Đây là một giải pháp thực sự tuyệt vời cho vấn đề. Tôi đã sửa đổi việc triển khai một chút để hỗ trợ khái niệm cài đặt bắt buộc. Chỉ một điều - hãy nhớ thêm using System.ComponentModel;câu lệnh vào lớp của bạn để hỗ trợ việc sử dụng TypeDescriptorlớp.
STLDev

3
var isAlaCarte = 
    ConfigurationManager.AppSettings.AllKeys.Contains("IsALaCarte") && 
    bool.Parse(ConfigurationManager.AppSettings.Get("IsALaCarte"));

2

Nếu khóa bạn đang tìm kiếm không có trong tệp cấu hình, bạn sẽ không thể chuyển đổi nó thành một chuỗi bằng .ToString () vì giá trị sẽ là null và bạn sẽ nhận được "Tham chiếu đối tượng không được đặt đến một thể hiện của một đối tượng "lỗi. Trước tiên, tốt nhất là xem giá trị có tồn tại hay không trước khi thử lấy biểu diễn chuỗi.

if (!String.IsNullOrEmpty(ConfigurationManager.AppSettings["myKey"]))
{
    String myKey = ConfigurationManager.AppSettings["myKey"].ToString();
}

Hoặc, như Code Monkey đề xuất:

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

2

Tùy chọn trên cho phép linh hoạt theo mọi cách, nếu bạn biết loại khóa hãy thử phân tích cú pháp chúng bool.TryParse(ConfigurationManager.AppSettings["myKey"], out myvariable);


2

Tôi nghĩ rằng biểu thức LINQ có thể là tốt nhất:

   const string MyKey = "myKey"

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

chắc chắn ... nhưng idunno - có bất kỳ lợi thế cho phương pháp này? Nếu tôi thực sự thành thạo trong LINQ (mà hầu hết C # lập trình viên có thể cuối cùng sẽ được), sau đó nó có lẽ sẽ dễ dàng để đọc ví dụ này, nhưng tôi không bao giờ nghĩ rằng nó sẽ là dễ dàng hơn - vì vậy, trừ khi có một lợi thế hiệu quả ... tại sao?

không có lợi thế hiệu quả và imo về mặt cú pháp.
John Nicholas

1
ConfigurationManager.AppSettingsAny(key => key == MyKeytuy nhiên không phân biệt chữ hoa chữ thường
janv8000

1

Tôi thích câu trả lời của codebender , nhưng cần nó để hoạt động trong C ++ / CLI. Đây là những gì tôi đã kết thúc với. Không có sử dụng LINQ, nhưng hoạt động.

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

0

Sử dụng cú pháp c # mới với TryPude hoạt động tốt với tôi:

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

Chào mừng đến với SO! Khi bạn gửi câu trả lời, hãy cố gắng giải thích một chút về giải pháp của bạn. Trong trường hợp này, có một vài câu trả lời nữa, hãy thử phơi bày Ưu điểm trong bạn.
David García Bodego
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.