過去在開發Class Library專案撰寫共用元件時,我常用HttpContext.Current != null來判別程式是否處於ASP.NET環境,再依ASP.NET環境或WindowForm/Console環境決定不同處理邏輯。例如: 若在ASP.NET中,就由App_Data讀取資料檔案;若為Console程式,就由EXE檔所在目錄讀檔。

但依經驗,判讀HttpContext.Current的做法會有例外狀況:

  • 若元件是在WCF Service程式中被呼叫,且WCF未開啟ASP.NET相容模式,HttpContext.Current將傳回null,造成誤判
  • 當ASP.NET透過其他Thread或ThreadPool執行程式時,HttpContext.Current也會傳回null

最近學會一個更簡便可靠的寫法--HostingEnvironment.IsHosted,看來可以克服前述問題,以下是範例:

using System;
using System.Web;
using System.Diagnostics;
using System.Threading;
using System.Web.Hosting;
 
public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        Thread t = new Thread(() =>
        {
            Debug.WriteLine("HttpContext.Current == null? {0}",
                HttpContext.Current == null); //True
            Debug.WriteLine("HostingEnvironment.IsHosted? {0}",
                HostingEnvironment.IsHosted); //True
        });
        t.Start();
        //BreakPoint
        Debug.WriteLine("For Debug");
    }
}

但我們接著還會遇到另一個常見的挑戰,沒有HttpContext.Current,原本用HttpContext.Current.Server.MapPath()取得路徑的做法不就沒搞頭了? 別怕,HostingEnvironment裡有解藥,請參閱相關文章: TIPS-在WCF中呼叫Server.MapPath


Comments

Be the first to post a comment

Post a comment