有個 ASP.NET 網站計劃提供兩種執行模式,「一般模式」依賴第三方服務 WebAPI 提供完整功能,當部署環境無第三方服務可用時,則透過 appSetting StandAloneMode = "Y" 切換成「獨立模式」只提供核心服務。如此一來,只需維護一份程式碼,部署時調整 web.config 便能切換成不同執行模式。

用 appSetting 切換已經蠻方便的,但開發測試時我還是遇到困擾。我有個私房偵錯技巧 - 將開發機上的專案目錄直接掛成 IIS 網站應用程式,如此即使不開 Visual Studio 也能測試,每次建置自動更新,網站寫起來格外順手。例如 ASP.NET 專案目錄長這樣:

不需另外 Publish,專案目錄直接掛在 IIS 下即可運作:

但是從上圖大家應該已想到這次我遇到的問題。我想用同一份原始碼同時測試一般跟獨立模式,所以掛了兩個網站應用程式 ASMW-N 及 ASMW-S。但因為模式由 appSettings 決定,ASMW-N、ASMW-S 共用 同一個 web.config,修改 appSetting StandAloneMode 時二者會一起變,無法達成 ASMW-N 跑一般模式,ASMW-S 跑獨立模式的目標。

靈機一動我想到一個好點子,讓程式偵測 AppPool 名稱來決定執行模式,IIS 有個 APP_POOL_ID 伺服器變數,是 ASP.NET 取得 AppPool ID 最簡便的方法。於是,我將決定執行模式的 StandaloneMode 屬性改寫如下,再將 ASMW-S 網站應用程式的 AppPool 命名為 ASMW-S:

using System;
using System.Configuration;

namespace DemoWeb.Models
{
    public class WebAppStates
    {
        static string AppPoolId =  System.Environment.GetEnvironmentVariable(
                  "APP_POOL_ID", EnvironmentVariableTarget.Process);
        public static bool StandaloneMode =
            AppPoolId == "ASMW-S" ||
            ConfigurationManager.AppSettings["StandAloneMode"] == "Y";
    }
}

隨便寫個 Action 驗證:

using DemoWeb.Models;
using System.Web.Mvc;

namespace DemoWeb.Controllers
{
    public class HomeController : Controller
    {
        // GET: Home
        public ActionResult Index()
        {
            return Content(
                $"網站狀態:{(WebAppStates.StandaloneMode ? "獨立" : "一般")}模式",
                "text/plain");
        }
    }
}

就醬,省去另外複製或發行一套程式的工夫,我用同一套專案原始碼跑兩種網站,開心!

Running ASP.NET web site in different mode according to AppPool ID to share the same source among IIS web applications.


Comments

# by Tom

Standalone…

# by Jeffrey

to Tom, 謝謝指正。(我得了一種不寫錯字就不會寫文章的病... Orz)

Post a comment