Pages

2014-09-10

ASP.NET Global.asax之事件未正常觸發原因

Gloalbal.asax(以下簡稱G檔)是ASP.NET站台在IIS中最先啟動執行的檔案,它的Application_Start(), Session_Start()可以應用在線上瀏覽人數統計等相關應用上,從ASP.NET 2.0以後我都有使用它,歷經很多網站架構的改朝換代,直到使用ASP.NET 4.0之後突然發現其檔案內的Event都沒被突發。網上搜尋的可能方法都試過N遍了,最後才歸納出一些結果。以下研究是以ASP.NET 4.0為例,架構在WIN2008R2 + IIS 7.5下,更舊.NET版本就不在本文研究範疇了。

Global.asax Excluded

當站台要發佈Release到正式主機時,通常我們會在Publish介面把各頁面的源碼編譯成一個Main DLL檔,除了能保護源碼及方便Copy佈署簡單外,頁面載入速度更快(因為CodeFile方式的自動編譯碼似乎會在某時間後被Recycle回收)。以下是以Single Assembly的發佈方式(編號1),而編號2主要的差別是把App_Code下的類別獨立成一個App_Code.dll而己。我個人偏好第一種方式,因為Library會以另外的專案加入,App_Code/下通常只放與專案UI連動的相關函式庫而己。

ASP.NET Publish

Publish前,若根目錄下的G檔存在(未被Excluded),它就會被編譯入主要的輸出DLL內,因此Deploy根目錄下不會出現G檔,並會自動產生「/Bin/App_global.asax.compiled」標示檔。因此,若想讓User日後能修改G檔源碼,記得先把Global.asax遮蔽(Exclude)再Publish,這樣產生的Main DLL就不會含有G檔編譯碼,接著手動將Global.asax複製至Deploy根目錄下,並移除或更名「/PrecompiledApp.config」及「/Bin/App_global.asax.compiled」兩個檔案。

根目錄之「PrecompiledApp.config」標示檔案,它的存在是告訴ASP.NET優先執行Main DLL下的編譯碼版本, 而非最新動態自動編譯的版本(若頁面使用CodeFile即時源碼編譯,則優先執行不受該檔存在與否影響)。因此要手動執行G檔源碼事件,PrecompiledApp.config必須移除或更名,否則會被Main DLL取代(假如它不含有G檔編譯)而不執行了。

最後,了解在Publish相關概念及差異後,若發現站台的G檔事件未能正確執行,也許它因為編譯方式及2個標示檔的存在與否,讓Main DLL檔給Override蓋掉了。

No comments: