.NET Magazine國際中文電子雜誌
作 者:許薰尹
審 稿:張智凱
文章編號: N200421803
出刊日期: 2020/4/29
在ASP.NET Core應用程式(ASP.NET Core App)2.2版之前,ASP.NET Core 應用程式(ASP.NET Core App)只能夠以跨處理序裝載模型(Out-of-process hosting model)方式運行,ASP.NET Core 應用程式(ASP.NET Core App)2.2版之後,提供了同處理序裝載模型(In-process hosting model)與跨處理序裝載模型(Out-of-process hosting model)可供選擇。
同處理序裝載模型(In-process hosting model)是ASP.NET Core應用程式2.2版後新增的功能,不使用Kestrel而是實作一個新的IISHttpServer網站伺服器,直接將ASP.NET Core 應用程式載入IIS 工作處理序 (IIS Worker Process,w3wp.exe)中執行。
Kestrel是一個跨平台的網站伺服器,可以讓ASP.NET Core網站應用程式執行於Windows、Mac以及Linux平台。
跨處理序裝載模型(Out-of-process hosting model)通常會讓前端網站伺服器(Web Server,可以是IIS、Nginx、Apache等等)充當反向 Proxy 伺服器(reverse proxy server)的角色,將請求轉送到後端的Kestrel伺服器上來執行。也就是你可能會使用到兩個處理序,執行ASP.NET Core 應用程式的處理序和IIS 工作處理序(w3wp.exe)是不同的。
因同處理序裝載模型(In-process hosting model)少了一層溝通的動作,就效能而言優於跨處理序裝載模型(Out-of-process hosting model)。不過在某些情況下,跨處理序裝載模型(Out-of-process hosting model)會是比較好的選擇,例如除錯、不使用IIS而是使用Nginx、Apache當外部網站伺服器時。
同時想要切換ASP.NET Core 應用程式使用同處理序裝載模型或跨處理序裝載模型也很簡單,只要透過一個Web.config檔案進行組態設定。在這篇文章中,將介紹ASP.NET Core 應用程式裝載(ASP.NET Core App Hosting)模式。
讓我們先利用Visual Studio 2019開發工具來建立一個ASP.NET Core 應用程式專案來了解裝載模型。
建立ASP.NET Core 應用程式專案
啟動Visual Studio 2019開發環境。從Visual Studio開發工具「File」-「New」-「Project」項目,在「Create a New Project」對話盒中,選取「ASP.NET Core Web Application」範本。請參考下圖所示:

圖 1:建立ASP.NET Core 應用程式專案。
在「Configure your new project」對話盒中,設定專案名稱與專案存放路徑,然後按下「Create」鍵,請參考下圖所示:

圖 2:設定專案名稱與專案存放路徑。
在「Create a new ASP.NET Core Web Application」對話盒中,確認左上方的清單選取「.NET Core」,右上方的清單ASP.NET Core版本為「ASP.NET Core 3.x」,選取下方的「Empty」樣版專案,清除勾選「Configure for HTTPS」、「Enable Docker Support」核取方塊,確定右方的「Authentication」項目設定為「No Authentication」,然後按下「Create」按鈕建立專案,請參考下圖所示:

圖 3:選取下方的「Empty」樣版專案。
修改專案中「Startup.cs」檔案程式碼如下,印出執行網站應用程式的處理程序名稱(Process Name):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
namespace MyWebApp {
public class Startup {
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices( IServiceCollection services ) {
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure( IApplicationBuilder app , IWebHostEnvironment env ) {
if ( env.IsDevelopment() ) {
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseEndpoints( endpoints => {
endpoints.MapGet( "/" , async context => {
await context.Response.WriteAsync( "Running on process : " + System.Diagnostics.Process.GetCurrentProcess().ProcessName );
await context.Response.WriteAsync( "\nFileName : " + System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName );
} );
} );
}
}
}
選取Visual Studio 2019開發工具「Build」-「Build Solution」項目編譯目前的專案,確認程式碼能正確編譯,完成後可以檢視「Output」視窗來得知編譯結果,請參考下圖所示:

圖 4:編譯目前的專案。
在執行網站之前,在Visual Studio 開發工具上方的選單,可以看到預設執行的按鈕旁顯示「IIS Express」字樣,請參考下圖所示:

圖 5:預設使用「IIS Express」執行。
在Visual Studio 2019開發工具,按「CTRL」+「F5」組合鍵來執行網站應用程式,此時會啟動瀏覽器,以及開發用的IIS Express伺服器,自動指定一個埠號(port)來執行網站應用程式。執行結果參考如下:

圖 6:執行網站應用程式。
從測試的結果可得知,使用Visual Studio 2019工具來建立ASP.NET Core網站應用程式時,預設是使用IIS Express(若部署到IIS的話,則會是w3wp.exe)來執行網站應用程式,採用同處理序裝載模型(In-process hosting model)。
若想要明確指定使用的裝載模型,可以修改專案檔案,加入<AspNetCoreHostingModel>設定。從「Solution Explorer」視窗專案名稱上方,按滑鼠右鍵,從快捷選單選擇Edit Project File」項目,請參考下圖所示:

圖 7:修改專案檔案。
在專案檔案加入<AspNetCoreHostingModel>設定,請參考以下範例程式碼,其值可以是「InProcess」同處理序裝載模型(In-process hosting model)或是「OutOfProcess」跨處理序裝載模型(Out-of-process hosting model),若專案中沒有這項設定,則預設值是「InProcess」;不過請注意,使用舊版工具建立的ASP.NET Core 2.2專案預設值是「OutOfProcess」。
MyWebApp.csproj
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
</PropertyGroup>
</Project>
在Visual Studio 2019開發工具,按「CTRL」+「F5」組合鍵來執行網站應用程式,執行結果和前文一樣,執行結果,請參考下圖所示:

圖 8:「InProcess」同處理序裝載模型(In-process hosting model)。
回到Visual Studio 2019開發工具,修改<AspNetCoreHostingModel>設定,這次我們將值設定為「OutOfProcess」,參考以下範例程式碼:
MyWebApp.csproj
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<AspNetCoreHostingModel>OutOfProcess</AspNetCoreHostingModel>
</PropertyGroup>
</Project>
目前網站的執行結果參考如下,ASP.NET Core應用程式會執行在專案編譯完的MyWebApp處理序(若是ASP.NET Core 2.2版則會是dotnet.exe):

圖 9:「OutOfProcess」跨處理序裝載模型(Out-of-process hosting model)。
同時在作業系統的工作管理員(Task Manager)也可以觀察到這個處理序,請參考下圖所示:

圖 10:「OutOfProcess」跨處理序裝載模型(Out-of-process hosting model)。
此外你也可以透過瀏覽器除錯工具Response Headers區段的資訊來進行觀察,例如網站執行時,在Chrome瀏覽器按下「F12」開啟除錯工具,在「Network」分頁中,可以看到請求的Response Headers中Server設定為Kestrel,表示它是「OutOfProcess」跨處理序裝載模型(Out-of-process hosting model),請參考下圖所示:

圖 11:「OutOfProcess」跨處理序裝載模型(Out-of-process hosting model)。
launchSettings.json檔案
當你透過Visual Studio建立專案時,在專案中會包含一個「launchSettings.json」檔案,以目前的範例而言,檔案內容參考如下:
launchSettings.json
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "
http://localhost:56169",
"sslPort": 0
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"MyWebApp": {
"commandName": "Project",
"launchBrowser": true,
"applicationUrl": "
http://localhost:5000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
而Visual Studio 2019開發工具上方的選單,可以看到執行按鈕旁的下拉式清單選項,則分別對應到「launchSettings.json」檔案中的「profiles」設定,請參考下圖所示:

圖 12:「profiles」設定。
你可以切換選單,使用不同的Profile設定來執行ASP.NET Core應用程式,想要使用IIS Express來執行時,便選擇「IIS Express」選單,根據設定會使用「"commandName": "IISExpress"」指令來執行;若選擇「專案名稱」選項,就會使用「"commandName": "Project"」指令來執行。我們先切換到使用專案的方式來執行,請參考下圖所示:

圖 13:使用「"commandName": "Project"」指令來執行。
目前專案檔案的內容如下:
MyWebApp.csproj
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
</Project>
而網站執行結果如下圖所示,使用「OutOfProcess」跨處理序裝載模型(Out-of-process hosting model):

圖 14:「OutOfProcess」跨處理序裝載模型(Out-of-process hosting model)。
回到Visual Studio 2019開發工具,修改專案檔案,明確設定使用「InProcess」同處理序裝載模型(In-process hosting model),請參考以下範例程式碼:
MyWebApp.csproj
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
</PropertyGroup>
</Project>
這次的執行結果還是一樣,使用「OutOfProcess」跨處理序裝載模型(Out-of-process hosting model),請參考下圖所示:

圖 15:「OutOfProcess」跨處理序裝載模型(Out-of-process hosting model)。。
從這個測試中,我們得到一個結論,使用「"commandName": "Project"」的方式來執行時,會忽略掉專案檔案中的<AspNetCoreHostingModel>的設定。
發行到IIS伺服器
一旦ASP.NET Core應用程式開發完成後,下一個階段該做的是就是考慮要如何裝載(Hosting)應用程式,讓外部使用者可以取用到這個網站,將網站程式部署到上線的伺服器這個過程就叫做裝載(Hosting)。而使用Visual Studio 2019發行功能將網站部署到IIS時,專案檔案中<AspNetCoreHostingModel>的設定會影響產生出來的組態檔案(Web.config)的設定。
在進行發行之前,目前專案檔案的內容如下:
MyWebApp.csproj
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
</Project>
從「Solution Explorer」視窗 - 專案上方按滑鼠右鍵,從快捷選單選擇「Publish」開啟「Publish」視窗,請參考下圖所示:

圖 16:「Publish」網站。
從「Profile」頁面中,選取「IIS,FTP, etc」,然後按下「Create Profile」按鈕,請參考下圖所示:

圖 17:建立Profile。
在「Publish」視窗中,選取「Connection」分頁 。設定「Publish method」為「Web Deploy」,設定「Server」為「localhost」,「Site name」輸入「Default Web Site/MyWebApp」,然後按一下「Validation Connection」按鈕,確認顯示一個綠色的圖示,表示連線驗證沒有問題,請參考下圖所示:

圖 18:「Connection」設定。
按「Next>」按鈕到「Settings」 頁面,確認「Configuration」下拉式清單方塊中,選取「Release」,「Target Frameowk」設定為「.netcoreapp 3.1」,注意目前「Deployment Mode」的設定為「Framework-Dependent」;然後按下「Save」按鈕,請參考下圖所示:

圖 19:「Settings」設定。
按下「Publish」按鈕,就會自動進行發行:

圖 20:發行網站。
完成後開啟瀏覽器,輸入網站網址「http://localhost/MyWebApp」,執行結果採用「InProcess」同處理序裝載模型(In-process hosting model),請參考下圖所示:

圖 21:「InProcess」同處理序裝載模型(In-process hosting model)。
預設發行完成後,相關的檔案會複製到「C:\inetpub\wwwroot\MyWebApp」資料夾中,在檔案總管中可以看到資料夾中包含一個Web.config檔案,請參考下圖所示:

圖 22:Web.config檔案。
使用文字編輯軟體檢視網站根目錄下的「web.config」檔案,可以看到在< aspNetCore >項目中設定了「hostingModel="inprocess"」,請參考以下範例程式碼:
web.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<location path="." inheritInChildApplications="false">
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath="dotnet" arguments=".\MyWebApp.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" hostingModel="inprocess" />
</system.webServer>
</location>
</configuration>
<!--ProjectGuid: 31e72365-079f-4a11-8bcf-d9fd2035ecd4-->
讓我們回到Visual Studio 2019開發工具,修改專案檔案的內容,明確指定<AspNetCoreHostingModel>項目,這次我們將它的值變更為「OutOfProcess」,請參考以下範例程式碼:
MyWebApp.csproj
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<!--<AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>-->
<AspNetCoreHostingModel>OutOfProcess</AspNetCoreHostingModel>
</PropertyGroup>
</Project>
再重複前面的動作,將網站發行到IIS伺服器,這次網站應用程式執行的結果便改用「OutOfProcess」跨處理序裝載模型(Out-of-process hosting model),請參考下圖所示:

圖 23:「OutOfProcess」跨處理序裝載模型(Out-of-process hosting model)。
使用文字編輯軟體檢視網站根目錄下的「web.config」檔案,可以看到在< aspNetCore >項目中設定了「hostingModel=" OutOfProcess "」,由於發行時「Deployment Mode」設定為「Framework-Dependent」因此可以組態檔案之中將看到「processPath="dotnet" arguments=".\MyWebApp.dll"」這個設定,請參考以下範例程式碼:
web.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<location path="." inheritInChildApplications="false">
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath="dotnet" arguments=".\MyWebApp.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" hostingModel="OutOfProcess" />
</system.webServer>
</location>
</configuration>
<!--ProjectGuid: 31e72365-079f-4a11-8bcf-d9fd2035ecd4-->