共用方式為


ASP.NET 與 IIS 7 整合

作者 :Mike Volodarsky

簡介

自發行以來,ASP.NET 是 Windows / IIS 平台上開發 Web 應用程式的平臺。 ASP.NET 2.0 讓 Web 應用程式開發成為新層級,讓開發人員能夠比之前更快建置更強大的應用程式。

IIS 7 和更新版本會藉由整合 ASP.NET 運行時間擴充性模型與核心伺服器,進一步 ASP.NET。 這可讓開發人員使用 ASP.NET 2.0 和 .NET Framework 豐富度來完整擴充 IIS 伺服器,而不是使用較不具功能的 IIS C++ API。 現有的 ASP.NET 應用程式也會使用窗體驗證、角色和輸出快取等現有 ASP.NET 功能,立即受益於更緊密的整合。

雖然 IIS 預設提供改良的 ASP.NET 整合,但有一個選擇:IIS 同時支援可在相同伺服器上並存使用的全新和舊 ASP.NET 整合模式。

本文討論 ASP.NET 整合模式、兩種模式的架構,以及如何選取和設定 ASP.NET 應用程式的整合模式。

ASP.NET IIS 7 和更新版本上的增強功能

IIS 中的較佳 ASP.NET 整合可增強現有的應用程式,並讓新的應用程式利用下列方式 ASP.NET 功能:

  • ASP.NET 服務可用於所有內容類型。 在過去,ASP.NET 窗體驗證、角色、URL 授權和輸出快取等功能只能 ASP.NET ASPX 頁面等內容類型。 靜態檔案、ASP 頁面和其他內容類型無法受益於這些服務。

在 IIS 中,所有 ASP.NET 服務都會統一提供給所有內容。 例如,您可以使用以窗體驗證、成員資格和登入控件 ASP.NET 為基礎建置的現有 ASP.NET 2.0 訪問控制解決方案,保護所有 Web 內容,包括影像和 ASP 頁面。

  • 使用 ASP.NET 完整擴充 IIS。 舊版 IIS 經常需要使用原生 ISAPI 篩選或擴充性模式開發的伺服器擴充性,因為 ASP.NET 的運行時間限制。

IIS 可讓 ASP.NET 模組直接插入伺服器管線,且運行時間精確度與使用原生 (C++) 伺服器 API 開發的模組相同。 ASP.NET 模組可以在要求處理管線的所有運行時間階段執行,而且可以依原生模組的任何順序執行。 ASP.NET API 也會擴充,以允許比先前可能更多的要求處理控制權。

  • 整合伺服器運行時間。 更緊密的 ASP.NET 整合也會整合 IIS 與 ASP.NET 之間的許多功能。

IIS 提供 IIS 和 ASP.NET 模組和處理程式的統一組態。 許多其他功能,包括自定義錯誤和追蹤,都已整合,以提供更好的管理和統一應用程式設計。

ASP.NET 整合架構

在 IIS 6.0 和舊版中,ASP.NET 實作為 IIS ISAPI 擴充功能。

在這些舊版中,IIS 會處理對 ASP.NET 內容類型的要求,然後將該要求轉送到裝載 ASP.NET 要求管線和頁面架構的 ASP.NET ISAPI DLL。 要求 non-ASP.NET 內容,例如 ASP 頁面或靜態檔案,是由 IIS 或其他 ISAPI 延伸模塊處理,而且無法 ASP.NET。

此模型的主要限制是 ASP.NET 模組和自訂 ASP.NET 應用程式程式代碼所提供的服務無法 non-ASP.NET 要求。 此外,ASP.NET 模組無法影響 ASP.NET 執行路徑前後發生的 IIS 要求處理某些部分。

顯示 I S 6 和 A S P 點 NET 管線的圖表。

圖 1:IIS 6.0 & ASP.NET 管線

在 IIS 中,ASP.NET 要求處理管線會直接重疊 IIS 管線,基本上會透過它提供包裝函式,而不是插入它。

IIS 會處理任何內容類型抵達的要求,而原生 IIS 模組和 ASP.NET 模組都會在所有階段提供要求處理。 這可讓 ASP.NET 模組所提供的服務,例如窗體驗證或輸出快取,用於對 ASP 頁面、PHP 頁面、靜態檔案等的要求。

直接插入伺服器管線的功能可讓 ASP.NET 模組取代、執行之前或執行任何 IIS 功能。 例如,這可讓自定義 ASP.NET 基本身份驗證模組,以使用成員資格服務和 SQL Server 用戶資料庫來取代僅適用於 Windows 帳戶的內建 IIS 基本身份驗證功能。

此外,擴充的 ASP.NET API 會使用直接整合來啟用更多要求處理工作。 例如,ASP.NET 模組可以在其他元件處理要求之前修改要求標頭,方法是在ASP應用程式執行之前插入 Accept-Language 標頭,以強制根據使用者喜好設定將當地語系化的內容傳回用戶端。

顯示 I S 7 和更新版本整合模式的圖表。

圖 2:IIS 7 和更新整合模式

由於運行時間整合,IIS 和 ASP.NET 可以使用相同的組態來啟用和排序伺服器模組,以及設定處理程序對應。 其他統一功能包括追蹤、自定義錯誤和輸出快取。

相容性

最值得注意的是,架構會維護 ASP.NET 運行時間架構和 API,這可讓現有的 ASP.NET 應用程式和服務在安裝時運作。 透過一些修改,現有的 ASP.NET 應用程式和服務可以利用新的 ASP.NET 功能。

同樣地,開發人員可以繼續撰寫新的應用程式,以熟悉 ASP.NET API,同時利用運行時間整合的優點。

IIS 會繼續為具有整合模式不符合特定相容性需求的 ASP.NET 應用程式提供傳統 ASP.NET 模式。 系統管理員可以為每個應用程式集區選取所需的整合模式,讓使用新的和傳統 ASP.NET 模式的應用程式在相同的伺服器上並存運作。

將 ASP.NET 應用程式遷移至 IIS 7 和更新整合模式

在 IIS 上,ASP.NET 預設會設定為在新的整合模式中運作。 這可讓您的應用程式利用最少修改的整合模式增強功能。

由於組態統一,某些應用程式可能需要移轉才能在整合模式中正常運作。 根據預設,伺服器會提供移轉的協助。 它會偵測需要移轉的應用程式,並傳回要求您移轉應用程式的錯誤訊息。

下列設定會導致移轉錯誤:

  1. 應用程式 Web.config 檔案會 <定義 HTTPModules 組> 態。
    應用程式會載入新的 ASP.NET 模組,或移除現有的模組。
    在整合模式中,ASP.NET 模組是在整合 <system.webServer>/<modules> 組態區段中使用原生模組來指定。
    system.web>/<HTTPModules> 組態區段中指定的 <ASP.NET 模組必須移至新的組態區段才會生效。 接著,必須將新的 ASP.NET 模組直接新增至整合 <modules> 區段。
  2. 應用程式 Web.config 檔案會 <httpHandlers> 定義組態。
    應用程式會針對某些內容類型使用自定義處理程序對應。
    在整合模式中,必須在整合 <system.webServer>/<handlers> 組態區段中指定 ASP.NET 處理程序對應,才能生效。 接著,必須將新的 ASP.NET 處理程序對應直接新增至整合 <handlers> 區段。
    本節會取代 ASP.NET <httpHandlers> 組態和 IIS scriptmaps 組態,這兩者先前都必須設定為設定 ASP.NET 處理程序對應。
  3. 應用程式 Web.config 檔案會 <定義身分識別模擬=“true” /> 組態。
    應用程式會模擬客戶端認證,這是內部網路應用程式最常見的認證。 在整合模式中,某些早期要求處理階段不提供用戶端模擬。 在大部分情況下,這不是問題,而且您可以關閉移轉錯誤。 否則,您必須將此應用程式設定為使用傳統 ASP.NET 模式來執行。

產生移轉錯誤時,通常會在 1 和 2、高於) 的情況下移轉應用程式組態 (,或將應用程式移至在 3) 的情況下使用傳統 ASP.NET 模式 (。

移轉應用程式組態

IIS 會使用 AppCmd.exe 命令行工具來移轉應用程式,以執行移轉。 移轉錯誤訊息包含命令行視窗中執行的命令,您必須以系統管理員使用者權力執行,才能立即將應用程式移轉至整合模式。

移轉命令的基本格式如下所示:

%windir%\system32\inetsrv\APPCMD.EXE migrate config <Application Path>

其中 <應用程式路徑> 是包含網站名稱的應用程式虛擬路徑,例如「預設網站/app1」。

移轉完成時,您的應用程式會在整合式和傳統模式中執行,而不會有任何問題。

注意

如果您在移轉後變更設定,伺服器將不會提示您再次移轉。 初始移轉之後,您必須確定組態在兩種模式之間保持同步。 您可以使用 AppCmd.exe 命令行工具,再次手動移轉應用程式。

回到傳統 ASP.NET 整合模式

如果您想要返回傳統 ASP.NET 模式,請將您的應用程式移至設定為在傳統模式中執行的應用程式集區。 其他應用程式會繼續在新的整合模式中與傳統模式應用程式並排執行。

如需如何將應用程式移至傳統 ASP.NET 模式的詳細資訊,請參閱變更應用程式的 ASP.NET 模式。

停用移轉錯誤訊息

如果您已手動移轉組態,或想要保持整合模式,而不建議您移轉設定 (不建議) ,您可以將下列內容新增至應用程式的 Web.config 檔案來停用移轉錯誤訊息:

<system.webServer> 
    <validation validateIntegratedModeConfiguration="false" />    
</system.webServer>

注意

伺服器使用 AppCmd.exe 命令行工具移轉組態之後,會自動停用錯誤訊息。

如果您手動停用移轉錯誤訊息,您必須確定應用程式在整合模式中正常運作,因為伺服器將不再提供任何有關不支援設定的警告。

變更應用程式的 ASP.NET 模式

如果您的應用程式無法在整合式 ASP.NET 模式中正常運作,您可以將它移至傳統 ASP.NET 模式,方法是將它移至另一個應用程式集區。 每個應用程式集區會個別設定為使用所需的整合模式 ASP.NET。 這可讓您在相同的伺服器上並排執行使用不同 ASP.NET 整合模式的應用程式群組。

若要變更應用程式的 ASP.NET 整合模式:

  1. 尋找或建立設定為使用所需模式的應用程式集區。
    根據預設,所有新的應用程式集區都會以整合模式執行。
    ASP.NET 設定提供名為 「Classic .NET AppPool」 的應用程式集區,可在傳統 ASP.NET 整合模式中執行。 您可以將此應用程式集區用於不應該在整合模式中執行的應用程式。
    您也可以使用 IIS 管理工具或 AppCmd.exe 命令行工具,或手動編輯應用程式集區組態,來變更現有應用程式集區的 ASP.NET 模式。
  2. 將應用程式設定為使用該應用程式集區。
    每個應用程式都會設定為使用特定的應用程式集區。 根據預設,所有應用程式都會使用名為 「DefaultAppPool」 的預設應用程式集區,以整合模式執行。
    您可以使用 IIS 管理工具或 AppCmd.exe 命令行工具,或手動編輯應用程式組態,來變更應用程式的應用程式集區。

選取應用程式的 ASP.NET 版本

在過去,IIS 支援多個版本的 ASP.NET / CLR 並存。 例如,IIS 允許相同的伺服器使用 .NET Framework v1.1 和 v2.0 來執行 ASP.NET 應用程式。 此支援是藉由對應對應的 ASPNET_isapi.dll 版本,以使用 IIS scriptmaps 組態來提供 ASP.NET 內容的要求。

例如,您可以使用下列 scriptmap 組態來啟用並存支援:

  1. ASP.NET /app1 上的 v1.1 應用程式:
    *.aspx -> d:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\aspnet_isapi.dll
  2. ASP.NET /app2 上的 v2.0 應用程式:
    *.aspx -> d:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll

當應用程式收到 *.aspx 要求時,IIS 會載入指定的 aspnet_isapi.dll,這會將正確的 CLR 版本載入背景工作進程,並處理要求。

ASP.NET 也提供下列方式來設定並存 scriptmap:

  1. ASP.NET MMC 擴充功能。 當您挑選要使用的 ASP.NET 版本時,延伸模組會自動設定腳本對應,讓應用程式指向正確的 aspnet_isapi.dll 版本。
  2. ASP.NET aspnet_regiis.exe。 使用 –i 和 –r 選項來安裝指向對應 ASP.NET 版本的 scriptmap。

不幸的是,由於將一個 CLR 版本載入單一背景工作進程的能力限制,您必須確定兩個使用不同版本 ASP.NET 的應用程式永遠不會設定為存在於相同的應用程式集區內。 發生這個常見的錯誤時,第一個要求會載入對應 aspnet_isapi.dll 的CLR,而相同應用程式集區內其他版本的後續要求將會失敗。

IIS 會辨識應用程式集區是您選取用來執行應用程式 ASP.NET 版本。 因此,應用程式集區組態中已明確設定載入應用程式集區中的CLR/ ASP.NET 版本。 根據預設,除非版本設定為空白) ,否則 IIS 會在載入背景工作進程 (時,預先載入此設定所指定的 CLR。

因為應用程式集區是 .NET Framework 版本控制界限,所以您可以執行下列動作來變更 ASP.NET 應用程式的版本:

  1. 將應用程式移至使用所需 ASP.NET 版本的應用程式集區。
    根據預設,應用程式會使用名為 「DefaultAppPool」 的預設應用程式集區,以整合模式執行 ASP.NET v2.1。 將應用程式移至「傳統 .NET AppPool」,以 ASP.NET v2.1 傳統模式或您選擇的另一個應用程式集區執行。
  2. 設定應用程式執行所在的應用程式集區,以使用所需的 ASP.NET 版本。
    根據預設,所有新的應用程式集區都會設定為在整合模式中執行 ASP.NET v2.1。

注意

請勿使用aspnet_regiis /i 或 /r 選項來設定特定應用程式或全域 ASP.NET 的版本。

IIS 會使用預先條件的處理程式對應,根據應用程式集區的已設定 CLR 版本和受控整合模式而定,自動選取正確的處理程式對應集 (,以在傳統模式中 ASPNET_isapi.dll) 或直接選取受控處理程序類型。 ASP.NET 2.0 安裝程式會在伺服器層級安裝這些處理程序對應。

利用整合式 ASP.NET 模式

在 IIS 上,ASP.NET 應用程式預設會以整合模式執行。 不過,若要利用更緊密整合所提供的優點,您必須對應用程式組態進行一些修改。 您也可以開發新的 ASP.NET 元件,利用整合模式為您的應用程式提供強大的功能。

為所有類型的內容類型啟用 ASP.NET 服務

在整合模式中,ASP.NET 模組所提供的服務可供所有內容類型的要求使用。 不過,根據預設,ASP.NET 模組只會針對 ASP.NET 內容的要求執行,以取得回溯相容性。

若要這樣做,請在伺服器層級的組態區段中,將 managedHandler 前置條件附加至每個 ASP.NET 模組:

<modules> 
     <add name="FormsAuthentication" type="System.Web.Security.FormsAuthenticationModule" 
             preCondition="managedHandler" />
     <add name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule" 
             preCondition="managedHandler" />
    ...
</modules>

前置條件是伺服器在每個要求上評估的規則,以判斷是否要執行模組。 managedHandler 前置條件僅適用於對應至 ASP.NET 處理程式之內容類型的要求。

若要將 ASP.NET 模組所提供的功能套用至所有要求,請移除模組專案,然後在應用程式的根 Web.config 檔案中沒有前置條件的情況下重新新增它。

若要啟用整個應用程式的 ASP.NET 窗體驗證,請修改您的 Web.config 檔案,如下所示:

<modules> 
    <remove name="FormsAuthentication" /> 
    <add name="FormsAuthentication" type="System.Web.Security.FormsAuthenticationModule" /> 
    …
</modules>

透過這項變更,FormsAuthentication 模組會針對您應用程式中的所有要求執行。 這可讓您使用窗體驗證來保護所有應用程式內容。 如需如何利用整合模式為所有應用程式內容提供窗體驗證的詳細資訊,請參閱 利用整合式管線模式逐步解說

您也可以使用快捷方式,讓所有受控 (ASP.NET) 模組針對您應用程式中的所有要求執行,而不論 「managedHandler」 前置條件為何。 若要讓所有 Managed 模組針對所有要求執行,而不需設定每個模組專案來移除 「managedHandler」 前置條件,請使用 區段中的 <modules>runAllManagedModulesForAllRequests 屬性:

<modules runAllManagedModulesForAllRequests="true" />

當您使用此條件時,「managedHandler」 前置條件沒有任何作用,而且所有 Managed 模組都會針對所有要求執行。

試驗讓其他 ASP.NET 模組套用至整個應用程式。 例如,使用 ASP.NET 輸出快取模組來輸出快取 ASP 頁面,或使用 URL 授權和角色管理員來設定相片的存取控制規則。 或者,開發您自己的模組,將 ASP.NET 功能帶入整個網站。

建置功能更強大的 ASP.NET 服務

在整合模式中,ASP.NET 模組將其服務套用至所有內容。 此外,由於 ASP.NET 模組會在整合式模式的整合要求處理管線中執行,因此會訂閱相同的要求處理階段,並執行與原生伺服器模組相同的工作。 同時,ASP.NET API 會維持大致相同,但有一些可解除鎖定先前無法使用功能的重要新增專案。

運行時間精確度

在整合模式中,ASP.NET 公開至模組的要求處理階段會直接連接到 IIS 管線的對應階段。 完整的管線包含下列階段,這些階段會在 ASP.NET 中公開為 HttpApplication 事件:

  1. BeginRequest。 要求處理隨即啟動。
  2. AuthenticateRequest。 要求已經過驗證。 IIS 和 ASP.NET 驗證模組訂閱此階段以執行驗證。
  3. PostAuthenticateRequest
  4. AuthorizeRequest。 要求已獲授權。 IIS 和 ASP.NET 授權模組會檢查已驗證的使用者是否可以存取所要求的資源。
  5. PostAuthorizeRequest
  6. ResolveRequestCache。 快取模組會檢查快取中是否有此要求的回應,並傳回它,而不是繼續執行路徑的其餘部分。 ASP.NET 輸出快取和 IIS 輸出快取功能都會執行。
  7. PostResolveRequestCache
  8. MapRequestHandler。 此階段是內部 ASP.NET,用來判斷要求處理程式。
  9. PostMapRequestHandler
  10. AcquireRequestState。 擷取要求執行所需的狀態。 ASP.NET 工作階段狀態和設定檔模組取得其數據。
  11. PostAcquireRequestState
  12. PreExecuteRequestHandler。 執行處理程式之前的任何工作。
  13. ExecuteRequestHandler。 要求處理程式會執行。 會提供 ASPX 頁面、ASP 頁面、CGI 程式和靜態檔案。
  14. PostExecuteRequestHandler
  15. ReleaseRequestState。 系統會儲存要求狀態變更,並在此清除狀態。 ASP.NET 工作階段狀態和設定檔模組會使用此階段進行清除。
  16. PostReleaseRequestState
  17. UpdateRequestCache。 回應會儲存在快取中以供日後使用。 ASP.NET 輸出快取和 IIS 輸出快取模組會執行,以將回應儲存至其快取。
  18. PostUpdateRequestCache
  19. LogRequest。 此階段會記錄要求的結果,而且保證即使發生錯誤也一樣執行。
  20. PostLogRequest
  21. EndRequest。 此階段會執行任何最終要求清除,而且保證即使發生錯誤也一樣執行。

藉由使用熟悉的 ASP.NET API,在與 IIS 模組相同的階段中執行的能力,讓工作只能在原生 ISAPI 篩選和擴充功能中存取,現在可以在 Managed 程式代碼中存取。

例如,您現在可以撰寫執行下列動作的模組:

  1. 在進行任何處理之前攔截要求,例如重寫 URL 或執行安全性篩選。
  2. 取代內建驗證模式。
  3. 修改傳入要求內容,例如要求標頭。
  4. 篩選所有內容類型的傳出回應。

如需如何使用自定義 ASP.NET 驗證模組擴充 IIS 的範例,請參閱 使用 .NET 開發 IIS 7 和更新 版本模組。

擴充 ASP.NET API

ASP.NET API 與舊版保持回溯相容,可讓現有的模組在 IIS 7 和更新版本中運作而不需修改,並套用至所有應用程式內容,而不需要變更程式代碼。

不過,針對 IIS 整合模式撰寫的模組可以利用一些額外的 API 來啟用先前未提供的重要要求處理案例。

新的 HttpResponse.Headers 集合可讓模組檢查及操作其他應用程式元件產生的響應標頭。 例如,您可以變更 ASP 頁面所產生的 Content-Type 標頭,以提示瀏覽器中的下載對話方塊。 HttpResponse 類別上的 Cookies 集合也會增強,以允許修改在要求處理過程中產生的 Cookie,即使它們是在 ASP.NET 之外建立也一樣。

HttpRequest.Headers 集合已啟用寫入功能,可讓模組操作傳入要求標頭。 使用此方法來變更其他伺服器元件的行為,例如,您可以動態變更 Accept-Language 標頭的值,強制當地語系化應用程式以不同的語言回應用戶端。

最後, HttpRequest.ServerVariables 集合現在是可寫入的,可設定 IIS 伺服器變數。 ASP.NET 模組會使用這項功能來變更 IIS 所提供的值,以及建立其他應用程式架構可見的新伺服器變數,例如 PHP。

運行時間整合

除了新的 API 之外,整合模式可讓現有的 ASP.NET 功能為您的應用程式提供更多價值。

ASP.NET 所提供的追蹤設備,包括 System.Diagnostics.Trace 類別和 ASP.NET 頁面追蹤功能,現在會在 IIS 追蹤系統中發出追蹤資訊。 這可讓 IIS 和 ASP.NET 元件在要求處理期間產生的追蹤資訊放在單一記錄檔中,以利進一步診斷伺服器問題。

ASP.NET 回應篩選功能可讓回應在移至用戶端之前先使用 Stream 介面進行變更,以允許篩選 non-ASP.NET 內容。 因此,您可以在所有伺服器內容上使用 ASP.NET 篩選,或選擇性地只針對您想要處理之內容的要求安裝篩選。 透過這項功能,您可以撰寫篩選功能,以插入或檢閱網站回應中的特定內容,不論此內容是來自 ASPX 頁面還是靜態檔案。

摘要

ASP.NET IIS 7 和更新版本中的整合可解除鎖定 ASP.NET 的完整可能性,讓開發人員能夠輕鬆且豐富地建立 ASP.NET 和 .NET Framework 的強大伺服器元件。 若要深入瞭解如何利用現有應用程式的 ASP.NET 整合模式,請參閱 利用整合式管線模式。 如需如何建置新的 ASP.NET 元件以擴充伺服器的資訊,請參閱 使用 .NET 開發 IIS 7 和更新版本模組