首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

C# 讀取與修改 App.config 完整指南:ConnectionStrings、AppSettings 與執行期更新

     編輯:關於C#

App.config 基礎結構




  
    
  
  
    
    
  

編譯後檔案說明

  • bin/Debug/App.exe.config:執行期實際讀寫的檔案,修改會持久化
  • bin/Debug/App.vshost.exe.config:VS 宿主進程用,同步自原始碼,執行期不修改
  • 重要:程式碼中操作的是 App.exe.config,部署時隨 EXE 一起發布

必要參考

  • 組件參考:System.Configuration.dll
  • 命名空間:using System.Configuration;

1. 讀取 ConnectionStrings


public static string GetConnectionString(string name)
{
    var cs = ConfigurationManager.ConnectionStrings[name];
    if (cs == null) throw new ConfigurationErrorsException($"找不到連線字串: {name}");
    return cs.ConnectionString;
}

// 使用
var connStr = GetConnectionString("DefaultConn");

2. 更新 ConnectionStrings (執行期修改並持久化)


public static void UpdateConnectionString(string name, string newConnectionString, string providerName = "System.Data.SqlClient")
{
    var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
    var cs = config.ConnectionStrings.ConnectionStrings[name];
    
    if (cs == null)
    {
        // 新增
        config.ConnectionStrings.ConnectionStrings.Add(
            new ConnectionStringSettings(name, newConnectionString, providerName));
    }
    else
    {
        // 修改:需先移除再加入 (ConnectionString 唯讀)
        config.ConnectionStrings.ConnectionStrings.Remove(name);
        config.ConnectionStrings.ConnectionStrings.Add(
            new ConnectionStringSettings(name, newConnectionString, providerName));
    }
    
    config.Save(ConfigurationSaveMode.Modified);
    ConfigurationManager.RefreshSection("connectionStrings"); // 重新整理快取
}

3. 讀取 AppSettings


// 簡單讀取
string title = ConfigurationManager.AppSettings["AppTitle"];
int maxRetry = int.Parse(ConfigurationManager.AppSettings["MaxRetryCount"] ?? "3");

// 強型別輔助
public static T GetAppSetting(string key, T defaultValue = default)
{
    var val = ConfigurationManager.AppSettings[key];
    if (val == null) return defaultValue;
    return (T)Convert.ChangeType(val, typeof(T));
}

4. 更新 AppSettings


public static void SetAppSetting(string key, string value)
{
    var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
    var settings = config.AppSettings.Settings;
    
    if (settings[key] == null)
        settings.Add(key, value);
    else
        settings[key].Value = value;
    
    config.Save(ConfigurationSaveMode.Modified);
    ConfigurationManager.RefreshSection("appSettings");
}

5. 完整範例:應用程式啟動時檢查/建立預設設定


public static class ConfigInitializer
{
    public static void EnsureDefaults()
    {
        var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
        
        // 確保連線字串存在
        if (config.ConnectionStrings.ConnectionStrings["DefaultConn"] == null)
        {
            config.ConnectionStrings.ConnectionStrings.Add(
                new ConnectionStringSettings("DefaultConn", 
                    "Data Source=.;Initial Catalog=MyDB;Integrated Security=True",
                    "System.Data.SqlClient"));
        }
        
        // 確保 AppSettings 存在
        var defaults = new Dictionary
        {
            ["AppTitle"] = "我的應用程式",
            ["MaxRetryCount"] = "3",
            ["LogLevel"] = "Information"
        };
        
        foreach (var kv in defaults)
        {
            if (config.AppSettings.Settings[kv.Key] == null)
                config.AppSettings.Settings.Add(kv.Key, kv.Value);
        }
        
        config.Save(ConfigurationSaveMode.Modified);
        ConfigurationManager.RefreshSection("connectionStrings");
        ConfigurationManager.RefreshSection("appSettings");
    }
}

6. 進階:自定義 ConfigurationSection


// 定義區段類別
public class MySettingsSection : ConfigurationSection
{
    [ConfigurationProperty("apiUrl", DefaultValue = "https://api.example.com", IsRequired = true)]
    public string ApiUrl => (string)this["apiUrl"];
    
    [ConfigurationProperty("timeout", DefaultValue = 30, IsRequired = false)]
    public int Timeout => (int)this["timeout"];
    
    [ConfigurationProperty("endpoints")]
    public EndpointCollection Endpoints => (EndpointCollection)this["endpoints"];
}

[ConfigurationCollection(typeof(EndpointElement), AddItemName = "endpoint")]
public class EndpointCollection : ConfigurationElementCollection
{
    protected override ConfigurationElement CreateNewElement() => new EndpointElement();
    protected override object GetElementKey(ConfigurationElement element) => ((EndpointElement)element).Name;
}

public class EndpointElement : ConfigurationElement
{
    [ConfigurationProperty("name", IsRequired = true, IsKey = true)]
    public string Name => (string)this["name"];
    
    [ConfigurationProperty("url", IsRequired = true)]
    public string Url => (string)this["url"];
}

// 註冊於 configSections
// 
// 使用 var section = (MySettingsSection)ConfigurationManager.GetSection("mySettings"); Console.WriteLine(section.ApiUrl); foreach (EndpointElement ep in section.Endpoints) Console.WriteLine($"{ep.Name}: {ep.Url}");

最佳實踐與注意事項

項目建議
修改後重新整理必須呼叫 ConfigurationManager.RefreshSection,否則後續讀取仍為舊值
執行緒安全ConfigurationManager 內部有鎖,但頻繁寫入會效能不佳,建議啟動時一次性讀取快取
權限問題寫入 Program Files 下的 config 需管理員權限,建議將可寫入設定存放於 Environment.GetFolderPath(SpecialFolder.LocalApplicationData)
加密敏感資料連線字串密碼建議使用 aspnet_regiis -pef connectionStrings 或 DPAPI 加密
.NET Core / 5+改用 appsettings.json + IConfiguration,不再使用 System.Configuration
使用者層級設定用 userSettings / Settings.Settings (專案屬性 → Settings),自動產生強型別類別,支援使用者/應用程式範圍

快速對照表


// 唯讀快取讀取
ConfigurationManager.AppSettings["key"]
ConfigurationManager.ConnectionStrings["name"].ConnectionString

// 讀寫並持久化
var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
config.AppSettings.Settings["key"].Value = "value";
config.ConnectionStrings.ConnectionStrings["name"].ConnectionString = "..."; // 唯讀,需 Remove/Add
config.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection("sectionName");

掌握 App.config 讀寫,能讓應用程式具備靈活的部署時配置與執行期自適應調整能力。

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