首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 更多程式設計知識

C# 讀寫 App.config/Web.config 完整指南:從基礎到進階

     編輯:更多程式設計知識

配置檔結構速覽

.NET 應用程式設定儲存在 app.config (桌面應用) 或 web.config (ASP.NET) 的 <appSettings> 區段:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <appSettings>
    <add key="IsInit" value="false" />
    <add key="ApiEndpoint" value="https://api.example.com" />
    <add key="MaxRetryCount" value="3" />
  </appSettings>
</configuration>

核心命名空間與類別

  • System.Configuration.ConfigurationManager:靜態入口,讀取/開啟配置。
  • System.Configuration.Configuration:可寫入的配置物件 (需 OpenExeConfiguration 取得)。
  • KeyValueConfigurationCollection:AppSettings.Settings 集合操作介面。

基礎讀寫封裝類

using System;
using System.Configuration;

namespace ConfigHelper
{
    public static class AppConfig
    {
        /// 
        /// 讀取設定值 (不存在回傳 null)
        /// 
        public static string Get(string key)
        {
            return ConfigurationManager.AppSettings[key];
        }

        /// 
        /// 讀取設定值,帶預設值與型別轉換
        /// 
        public static T Get(string key, T defaultValue = default)
        {
            string val = ConfigurationManager.AppSettings[key];
            if (val == null) return defaultValue;

            try
            {
                // 支援基本型別、Enum、Guid、TimeSpan 等
                var converter = System.ComponentModel.TypeDescriptor.GetConverter(typeof(T));
                return (T)converter.ConvertFromString(val);
            }
            catch
            {
                return defaultValue;
            }
        }

        /// 
        /// 寫入/更新設定值 (持久化到檔案)
        /// 
        public static void Set(string key, string value)
        {
            // 1. 開啟可寫入的配置物件 (當前執行檔層級)
            var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);

            // 2. 修改或新增
            var settings = config.AppSettings.Settings;
            if (settings[key] == null)
                settings.Add(key, value);
            else
                settings[key].Value = value;

            // 3. 儲存 (Modified: 僅儲存變更區段)
            config.Save(ConfigurationSaveMode.Modified);

            // 4. 強制重新整理快取,後續 Get 立即生效
            ConfigurationManager.RefreshSection("appSettings");
        }

        /// 
        /// 批次寫入 (單次儲存,效能更好)
        /// 
        public static void SetBatch(IDictionary keyValues)
        {
            var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            var settings = config.AppSettings.Settings;

            foreach (var kv in keyValues)
            {
                if (settings[kv.Key] == null)
                    settings.Add(kv.Key, kv.Value);
                else
                    settings[kv.Key].Value = kv.Value;
            }

            config.Save(ConfigurationSaveMode.Modified);
            ConfigurationManager.RefreshSection("appSettings");
        }

        /// 
        /// 刪除設定
        /// 
        public static void Remove(string key)
        {
            var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            if (config.AppSettings.Settings[key] != null)
            {
                config.AppSettings.Settings.Remove(key);
                config.Save(ConfigurationSaveMode.Modified);
                ConfigurationManager.RefreshSection("appSettings");
            }
        }
    }
}

使用範例

// 讀取字串
string endpoint = AppConfig.Get("ApiEndpoint"); 

// 讀取整數 (帶預設值)
int maxRetry = AppConfig.Get("MaxRetryCount", 3);

// 讀取布林
bool isInit = AppConfig.Get("IsInit", false);

// 寫入單值
AppConfig.Set("IsInit", "true");
AppConfig.Set("LastLogin", DateTime.Now.ToString("o"));

// 批次寫入 (應用啟動時初始化多項設定)
AppConfig.SetBatch(new Dictionary
{
    { "WindowWidth", "1200" },
    { "WindowHeight", "800" },
    { "Theme", "Dark" }
});

// 刪除
AppConfig.Remove("ObsoleteKey");

進階主題與避坑指南

主題 說明 最佳實踐
作用域層級 ConfigurationUserLevel.None = 應用程式層級 (exe.config)
PerUserRoamingAndLocal = 使用者層級 (user.config)
桌面應用通常用 None;需使用者個人化設定時用 PerUser
Web.config 特殊性 ASP.NET 執行於 IIS 背景進程,OpenExeConfiguration 需指定實體路徑 Web 環境建議改用 WebConfigurationManager 或直接操作 ConfigurationManager (IIS 7+ 整合模式自動映射)
執行時修改不生效 未呼叫 RefreshSection 或快取未失效 寫入後必呼叫 ConfigurationManager.RefreshSection("appSettings")
權限問題 寫入 Program Files 下的 exe.config 需管理員權限 生產環境將可寫入設定移至 user.config 或 AppData 目錄自訂 JSON/XML
加密敏感值 連線字串、API Key 不應明文 使用 config.SectionInformation.ProtectSection("DataProtectionConfigurationProvider") 或外部 Vault
強型別設定類別 大型專案建議定義 ConfigurationSection 衍生類別 獲得 IntelliSense、編譯期檢查、預設值、驗證邏輯

強型別設定類別範例 (進階)

using System.Configuration;

public class AppSettingsSection : ConfigurationSection
{
    [ConfigurationProperty("isInit", DefaultValue = false, IsRequired = true)]
    public bool IsInit
    {
        get => (bool)this["isInit"];
        set => this["isInit"] = value;
    }

    [ConfigurationProperty("apiEndpoint", DefaultValue = "https://api.default.com", IsRequired = true)]
    [RegexStringValidator(@"^https?://.+")]
    public string ApiEndpoint
    {
        get => (string)this["apiEndpoint"];
        set => this["apiEndpoint"] = value;
    }

    [ConfigurationProperty("maxRetry", DefaultValue = 3, IsRequired = false)]
    [IntegerValidator(MinValue = 0, MaxValue = 10)]
    public int MaxRetry
    {
        get => (int)this["maxRetry"];
        set => this["maxRetry"] = value;
    }
}

// 註冊於 config 檔:
// <configSections>
//   <section name="myApp" type="Namespace.AppSettingsSection, AssemblyName" />
// </configSections>
// <myApp isInit="false" apiEndpoint="https://api.example.com" maxRetry="3" />

// 使用:
var section = (AppSettingsSection)ConfigurationManager.GetSection("myApp");
bool init = section.IsInit; // 強型別、自動驗證

現代替代方案:appsettings.json + IOptions (ASP.NET Core / .NET 5+)

新專案強烈建議使用 JSON 配置 + 選項模式:

// appsettings.json
{
  "AppSettings": {
    "IsInit": false,
    "ApiEndpoint": "https://api.example.com",
    "MaxRetryCount": 3
  }
}

// 註冊 (Program.cs / Startup.cs)
builder.Services.Configure(builder.Configuration.GetSection("AppSettings"));

// 注入使用
public class MyService
{
    private readonly AppSettings _settings;
    public MyService(IOptions options) => _settings = options.Value;
    
    public void DoWork() => Console.WriteLine(_settings.ApiEndpoint);
}

// 熱更新支援
builder.Services.Configure(builder.Configuration.GetSection("AppSettings"));
// 配合 IOptionsMonitor 或 IOptionsSnapshot

結語

ConfigurationManager 是 .NET Framework 經典配置存取 API,雖然 API 略顯繁瑣,但掌握 OpenExeConfiguration → 修改 Settings → Save(Modified) → RefreshSection 這四步核心流程,即能應付絕大多數讀寫需求。新專案請優先擁抱 appsettings.json + IOptions,享受強型別、依賴注入、熱更新、環境區隔 (Development/Staging/Production) 等現代化配置體驗。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved