EKsumic's Blog

let today = new Beginning();

Click the left button to use the catalog.

OR

從 WinForms 到 Web:重用 App.config 的 Settings.Designer.cs 改造實踐

前言

隨著軟件應用從桌面遷移到 Web 平台,開發者經常面臨如何在新的架構下重用現有代碼的挑戰。對於基於 WinForms 的桌面應用程序,Settings.Designer.cs 和 App.config 是一種常見的配置管理模式,然而,當這些代碼直接移植到 Wisej.NET 或 ASP.NET 的 Web 項目中時,會遇到一些兼容性問題,因為 Web 項目通常使用的是 Web.config 而非 App.config。

為了避免重寫大量的配置代碼,同時保留與原有 App.config 的關聯性,我們可以對 Settings.Designer.cs 進行定制化改造,使其在 Web 項目中也能直接使用原來的配置文件。本篇文章將詳細講解如何通過簡單的代碼重構,實現從桌面到 Web 的配置管理無縫遷移,並以 Wisej.NET 和 ASP.NET 為例,分享實現過程中的實用技巧與注意事項。

希望本篇文章能為面臨相似需求的開發者提供思路與解決方案,助力項目高效遷移!

 

Settings.Designer.cs

修改前:

//------------------------------------------------------------------------------
// <auto-generated>
//     このコードはツールによって生成されました。
//     ランタイム バージョン:4.0.30319.42000
//
//     このファイルへの変更は、以下の状況下で不正な動作の原因になったり、
//     コードが再生成されるときに損失したりします。
// </auto-generated>
//------------------------------------------------------------------------------

namespace <PROJECT_NAME>.Properties {
    
    
    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.11.0.0")]
    internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
        
        private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
        
        public static Settings Default {
            get {
                return defaultInstance;
            }
        }
        
        [global::System.Configuration.UserScopedSettingAttribute()]
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [global::System.Configuration.DefaultSettingValueAttribute("")]
        public string DataFolder {
            get {
                return ((string)(this["DataFolder"]));
            }
            set {
                this["DataFolder"] = value;
            }
        }
        
        [global::System.Configuration.UserScopedSettingAttribute()]
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [global::System.Configuration.DefaultSettingValueAttribute("True")]
        public bool UpgradeFlag {
            get {
                return ((bool)(this["UpgradeFlag"]));
            }
            set {
                this["UpgradeFlag"] = value;
            }
        }
        
        [global::System.Configuration.UserScopedSettingAttribute()]
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [global::System.Configuration.DefaultSettingValueAttribute("0")]
        public int PrintMode {
            get {
                return ((int)(this["PrintMode"]));
            }
            set {
                this["PrintMode"] = value;
            }
        }
        
        [global::System.Configuration.UserScopedSettingAttribute()]
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [global::System.Configuration.DefaultSettingValueAttribute("2")]
        public int DateFormat {
            get {
                return ((int)(this["DateFormat"]));
            }
            set {
                this["DateFormat"] = value;
            }
        }
        
        [global::System.Configuration.ApplicationScopedSettingAttribute()]
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [global::System.Configuration.SpecialSettingAttribute(global::System.Configuration.SpecialSetting.ConnectionString)]
        [global::System.Configuration.DefaultSettingValueAttribute("Data Source=<SERVER_NAME>;Initial Catalog=<DATABASE_NAME>;Integrated Security=False;User ID=<USER_NAME>;Password=<PASSWORD>;TrustServerCertificate=True")]
        public string SqlConnectionString {
            get {
                return ((string)(this["SqlConnectionString"]));
            }
        }
        
        [global::System.Configuration.ApplicationScopedSettingAttribute()]
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [global::System.Configuration.SpecialSettingAttribute(global::System.Configuration.SpecialSetting.ConnectionString)]
        [global::System.Configuration.DefaultSettingValueAttribute("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|\\AccessDatabase.accdb")]
        public string AccessConnectionString {
            get {
                return ((string)(this["AccessConnectionString"]));
            }
        }
    }
}

修改后:

using System.Configuration;

namespace <PROJECT_NAME>.Properties
{
    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.12.0.0")]
    internal sealed partial class Settings : ApplicationSettingsBase
    {
        private static readonly Configuration AppConfig;

        static Settings()
        {
            // 指定 app.config 文件的路徑
            var configFileMap = new ExeConfigurationFileMap
            {
                ExeConfigFilename = System.Web.Hosting.HostingEnvironment.MapPath("~/app.config") // 確保 app.config 放在應用目錄
            };

            // 加載配置文件
            AppConfig = ConfigurationManager.OpenMappedExeConfiguration(configFileMap, ConfigurationUserLevel.None);
        }

        private object GetAppConfigValue(string key, object defaultValue)
        {
            // 嘗試從 AppSettings 中獲取值,若不存在則返回默認值
            return AppConfig.AppSettings.Settings[key]?.Value ?? defaultValue;
        }

        private void SetAppConfigValue(string key, string value)
        {
            // 更新 AppSettings 中的值
            if (AppConfig.AppSettings.Settings[key] != null)
            {
                AppConfig.AppSettings.Settings[key].Value = value;
            }
            else
            {
                AppConfig.AppSettings.Settings.Add(key, value);
            }

            // 保存並刷新配置
            AppConfig.Save(ConfigurationSaveMode.Modified);
            ConfigurationManager.RefreshSection("appSettings");
        }

        public static Settings Default { get; } = new Settings();

        [global::System.Configuration.UserScopedSettingAttribute()]
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [global::System.Configuration.DefaultSettingValueAttribute("")]
        public string DataFolder
        {
            get
            {
                return (string)GetAppConfigValue("DataFolder", "");
            }
            set
            {
                SetAppConfigValue("DataFolder", value);
            }
        }

        [global::System.Configuration.UserScopedSettingAttribute()]
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [global::System.Configuration.DefaultSettingValueAttribute("True")]
        public bool UpgradeFlag
        {
            get
            {
                bool.TryParse((string)GetAppConfigValue("UpgradeFlag", "True"), out bool result);
                return result;
            }
            set
            {
                SetAppConfigValue("UpgradeFlag", value.ToString());
            }
        }

        [global::System.Configuration.UserScopedSettingAttribute()]
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [global::System.Configuration.DefaultSettingValueAttribute("0")]
        public int PrintMode
        {
            get
            {
                int.TryParse((string)GetAppConfigValue("PrintMode", "0"), out int result);
                return result;
            }
            set
            {
                SetAppConfigValue("PrintMode", value.ToString());
            }
        }

        [global::System.Configuration.UserScopedSettingAttribute()]
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [global::System.Configuration.DefaultSettingValueAttribute("2")]
        public int DateFormat
        {
            get
            {
                int.TryParse((string)GetAppConfigValue("DateFormat", "2"), out int result);
                return result;
            }
            set
            {
                SetAppConfigValue("DateFormat", value.ToString());
            }
        }

        [global::System.Configuration.ApplicationScopedSettingAttribute()]
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [global::System.Configuration.SpecialSettingAttribute(global::System.Configuration.SpecialSetting.ConnectionString)]
        [global::System.Configuration.DefaultSettingValueAttribute("Data Source=<SERVER_NAME>;Initial Catalog=<DATABASE_NAME>;Integrated Security=False;User ID=<USER_NAME>;Password=<PASSWORD>;TrustServerCertificate=True")]
        public string SqlConnectionString
        {
            get
            {
                return AppConfig.ConnectionStrings.ConnectionStrings["SqlConnectionString"]?.ConnectionString
                    ?? "Data Source=<SERVER_NAME>;Initial Catalog=<DATABASE_NAME>;Integrated Security=False;User ID=<USER_NAME>;Password=<PASSWORD>;TrustServerCertificate=True";
            }
        }

        [global::System.Configuration.ApplicationScopedSettingAttribute()]
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [global::System.Configuration.SpecialSettingAttribute(global::System.Configuration.SpecialSetting.ConnectionString)]
        [global::System.Configuration.DefaultSettingValueAttribute("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|\\AccessDatabase.accdb")]
        public string AccessConnectionString
        {
            get
            {
                return AppConfig.ConnectionStrings.ConnectionStrings["AccessConnectionString"]?.ConnectionString
                    ?? "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|\\AccessDatabase.accdb";
            }
        }
    }
}

提醒: 為了更直觀地了解代碼的差異,建議將文章中的修改前和修改後代碼分別複製保存下來,並使用工具如 WinMergeBeyond CompareVS Code 的文件比較功能,對兩段代碼進行 DIFF 對比。這樣可以更清楚地查看具體改動之處,方便學習和應用。

希望本文對您有所幫助,歡迎留言交流或分享您的改造經驗!

This article was last edited at 2024-12-05 17:44:48

Today's comments have reached the limit. If you want to comment, please wait until tomorrow (UTC-Time).

There is 14h02m11s left until you can comment.