我們在《上篇》利用dotnet new指令建立了一個簡單的控制台程式,接下來我們将它改造成一個ASP.NET Core應用。一個ASP.NET Core應用建構在ASP.NET Core架構之上,ASP.NET Core架構利用一個消息處理管道完成對HTTP請求的監聽、接收、處理和最終的響應。ASP.NET Core管道由一個伺服器(Server)和若幹中間件(Middleware)構成,當宿主(Host)程式啟動之後,管道被建構出來,作為管道“龍頭”的伺服器開始監聽來自用戶端的HTTP請求。
一、添加引用
接下來我們直接利用Visual Studio 打開前面這個helloworld.csproj項目檔案。為了能夠使用ASP.NET Core 架構提供的程式集,我們可以通過修改項目檔案(.csproj)添加針對“Microsoft.AspNetCore.App”的架構引用(FrameworkReference)。在Visual Studio中修改項目檔案非常友善,我們隻需要右鍵選擇目标項目,并從彈出的菜單中選擇“Edit Project File”就可以了。如下所示的是修改後的項目檔案,針對“Microsoft.AspNetCore.App”的架構引用被添加到<ItemGroup/>節點下。
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App"/>
</ItemGroup>
</Project>
二、注冊伺服器與中間件
從應用承載或者寄宿(Hosting)方面來看,.NET Core具有一個以IHost/IHostBuilder為核心的服務承載系統,任何需要長時間運作的操作都可以定義成IHostedService服務并通過該系統來承載。IHost對象可以視為所有承載服務的宿主(Host),而IHostBuilder對象則是它的建構者(Builder)。一個ASP.NET Core應用本質上就是一個用來監聽、接收和處理HTTP請求的背景服務,是以它被定義成一個GenericWebHostService(實作了IHostedService接口),我們将它注冊到承載系統中進而實作了針對ASP.NET Core應用的承載。
一個運作的ASP.NET Core應用本質上展現為由一個伺服器和若幹中間件構成的消息處理管道,伺服器解決針對HTTP請求的監聽、接收和最終的響應,具體針對請求的處理則由它遞交給後續的中間件來完成。這個管道是由前面提到的GenericWebHostService服務建構出來的。
ASP.NET Core提供了幾種原生的服務類型,比較常用的是KestrelServer和HTTP.sys。KestrelServer是一款跨平台的Web伺服器,可以在Windows、Mac OS和Linux上使用。它不僅可以作為獨立的Web伺服器直接對外提供服務,也可以結合傳統的Web伺服器(比如IIS、Apache和NGinx)并将它們作為反向代理來使用。HTTP.sys則是一種隻能在Windows平台使用的Web伺服器,由于它本質上是一個在作業系統核心模式運作的驅動,是以能夠提供非常好的性能。
在對項目檔案helloworld.csproj作了上述修改之後,我們對定義在Program.cs中的Main方法做了如下的改造。我們調用了靜态類型Host的CreateDefaultBuilder方法建立了一個IHostBuilder對象,并最終調用該對象的Build方法建構出作為服務宿主的IHost對象。當我們調用IHost對象的Run擴充方法的時候,ASP.NET Core應用程式将會被啟動。
在調用Build方法建構IHost對象之前,我們調用IHostBuilder接口的ConfigureWebHost擴充方法,并利用指定的Action<IWebHostBuilder>委托對象建構出ASP.NET Core應用的請求處理管道。具體來說,我們調用IWebHostBuilder接口的UseKestrel擴充方法将KestrelServer注冊為伺服器,調用Configure擴充方法注冊了用來處理請求的中間件。Configure方法的輸入參數是一個Action<IApplicationBuilder>對象,所需的中間件就注冊在IApplicationBuilder對象上。示範程式注冊的唯一中間件是通過調用IApplicationBuilder接口的Run擴充方法注冊的,該中間件利用指定的Func<HttpContext,Task>對象将響應的主體内容設定為“Hello World”。
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Hosting;
namespace helloworld
{
class Program
{
static void Main()
{
Host.CreateDefaultBuilder()
.ConfigureWebHost(webHostBuilder => webHostBuilder
.UseKestrel()
.Configure(app => app.Run(
context => context.Response.WriteAsync("Hello World."))))
.Build()
.Run();
}
}
}
我們可以按照上面示範的那樣通過執行dotnet指令行來啟動該程式,也可以直接在Visual Studio中按F5或者Ctrl+F5啟動該程式。下圖所示的是執行dotnet run指令後控制台的輸出結果,這些輸出其實是通過日志的形式輸出的。我們從這些輸出可以看出ASP.NET Core應用采用的預設監聽位址(http//localhost:5000和https//localhost:5001)和承載環境(Production)。如果需要關閉應用程式,隻需要按Ctrl+C組合鍵就可以了。
注冊的KestrelServer伺服器會綁定到http//localhost:5000和https//localhost:5001這兩個位址監聽請求,如果我們利用浏覽器分别對這兩個位址發起請求會得到怎樣的響應呢?如下圖所示,兩個請求都會得到主體内容為“Hello World.”的響應(由于證書的問題,Chrome浏覽器為HTTPS的請求會顯示“Not secure”的警告),毫無疑問該内容就是我們注冊的中間件寫入的。
三、修改SDK
每個.NET Core應用都針對一種具體的SDK類型。我們在前面展示了項目檔案helloworld.csproj的完整定義,這是一個XML檔案,根節點的<Project>上通過SDK屬性設定了目前項目采用的SDK類型。對于前面這個通過dotnet new指令工具建立出來的控制台應用,它預設采用的SDK類型為“Microsoft.NET.Sdk”。對于一個ASP.NET Core應用,我們一般會采用另一種名為“Microsoft.NET.Sdk.Web”的SDK類型。
如果将SDK設定為“Microsoft.NET.Sdk.Web”,我們甚至可以将針對“Microsoft.AspNetCore.App”的架構引用從項目檔案中删除。由于我們并不需要利用生成的.exe檔案來啟動ASP.NET Core應用,是以我們也應該将XML元素<OutputType>Exe</OutputType>從<PropertyGroup>節點中删除,是以最終的項目檔案隻需要保留如下的内容就可以了。
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp3.0</TargetFramework>
</PropertyGroup>
</Project>
四、launchSettings.json
當我們通過修改項目檔案helloworld.csproj将SDK改為“Microsoft.NET.Sdk.Web”之後,如果我們使用Visual Studio打開這個檔案,一個名為“launchSettings.json”的配置檔案将自動生成并被儲存在“Properties”目錄下。顧名思義,launchSettings.json是一個在應用啟動的時候自動加載的配置檔案,該配置檔案使我們可以在不同的設定下執行我們的應用程式。如下所示的就是Visual Studio自動建立的launchSettings.json檔案的内容。我們可以看出該配置檔案預設添加了兩個節點,其中“iisSettings”用于設定IIS相關的選項,而“profiles”節點定義了一系列用于表示應用啟動場景的Profile。
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:51127/",
"sslPort": 0
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"helloworld": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "http://localhost:51128/"
}
}
}
初始的launchSettings.json檔案會預設建立兩個Profile,一個被命名為“IIS Express”,另一個則使用目前項目名稱來命名(“helloworld”)。每一個Profile相當于定義了應用的啟動場景,相關的設定包括應用啟動的方式、環境變量和URL等,具體的設定包括:
- commandName:啟動目前應用程式的指令類型,有效的選項包括IIS、IISExpress、Executable和Project,前三個選項分别表示采用IIS、IISExpress和指定的可執行檔案(.exe)來啟動應用程式。如果我們使用dotnet run指令來啟動程式,對應Profile的啟動命名名稱應該設定為Project。
- executablePath:如果commandName屬性被設定為Executable,我們需要利用該屬性來設定啟動可執行檔案的路徑(絕對路徑或者相對路徑)。
- environmentVariables:該屬性用來設定環境變量。由于launchSettings.json僅僅使用在開發環境,是以預設會添加一個名為“ASPNETCORE_ENVIRONMENT”的環境變量,并将它的值設定為“Development”,ASP.NET Core應用中正是利用這樣一個環境變量來表示目前的部署環境。
- commandLineArgs:指令行參數,即傳入Main方法的參數清單。
- workingDirectory:啟動目前應用運作的工作目錄。
- applicationUrl:應用程式采用的URL清單,多個URL之間采用分号(“;”)進行分隔。
- launchBrowser:一個布爾類型的開關,表示應用程式的時候是否自動啟動浏覽器。
- launchUrl:如果launchBrowser被設定為true,浏覽器采用的初始化路徑通過該屬性進行設定。
- nativeDebugging:是否啟動本地代碼調試(Native Code Debugging),預設值為false。
- externalUrlConfiguration:如果該屬性被設定為true,意味着禁用本地的配置,預設值為false。
- use64Bit:如果commandName屬性設定為IIS Express,該屬性決定是采用X64版本還是X86版本,預設值為false,意味着ASP.NET Core應用預設會采用X86版本的IIS Express。
launchSettings.json檔案中的所有設定僅僅針對開發環境,産品環境下是不需要這個檔案的,應用釋出後生成的檔案清單中也不包含該檔案。該檔案不需要手工進行編輯,目前項目屬性對話框(通過在解決方案對話框中右擊選擇“屬性(Properties)”選項)中“調試(Debug)”頁籤下的所有設定最終都會展現在該檔案上。
如果在launchSettings.json檔案設定了多個Profile,它們會以如下圖所示的形式出現在Visual Studio的工具欄中,我們可以選擇任意一個Profile中定義的配置選項來啟動目前應用程式。如果Profile中通過設定launchBrowser屬性選擇啟動浏覽器,我們還可以選擇浏覽器的類型。
如果我們在目前項目所在目錄下通過執行dotnet run指令來啟動應用程式,launchSettings.json檔案會預設被加載。我們可以通過指令行參數--launch-profile指定采用的Profile。如果沒有對Profile作顯式指定,定義在該配置檔案中第一個commandName為“Project”的Profile會預設被使用。如下圖所示,我們在建立的應用根目錄下通過執行dotnet run指令啟動我們的應用程式,其中第一次執行dotnet run指令的時候顯式設定了Profile名稱(--launch-profile helloworld)。從輸出的結果可以看出,兩次采用的是同一個Profile。
如果在執行dotnet run指令的時候不希望加載launchSettings.json檔案,我們可以通過顯式指定指令行參數--no-launch-profile來實作。如下圖所示,我們在執行dotnet run指令時指定了--no-launch-profile參數,是以應用會采用KestrelServer預設的監聽位址(http://localhost:5000和https://localhost:5001)。由于launchSettings.json根本就沒有被加載,是以目前執行環境從Development變成了預設的Production。
五、顯式指定URL
如果既不想使用launchSettings.json檔案中定義的URL,也不想使用KestrelServer預設采用的監聽位址,我們可以在應用程式中顯式指定應用的URL。如下面的代碼片段所示,我們隻需要調用IWebHostBuilder的擴充方法UseUrls指定一組以分号分隔的URL即可。
class Program
{
static void Main()
{
Host.CreateDefaultBuilder()
.ConfigureWebHost(webHostBuilder => webHostBuilder
.UseKestrel()
.UseUrls("http://0.0.0.0:3721;https://0.0.0.0:9527")
.Configure(app => app.Run(context => context.Response.WriteAsync("Hello World."))))
.Build()
.Run();
}
}
六、ConfigureWebHostDefaults
在上面示範的執行個體中,我們都是調用IHostBuilder接口的ConfigureWebHost擴充方法借助指定的Action<IWebHostBuilder>委托對象來建構處理請求處理管道,該接口還有另一個ConfigureWebHostDefaults的擴充方法,它會為我們作一些預設設定。如下面的代碼片段所示,如果調用這個方法,KestrelServer伺服器都不需要進行顯式注冊。
class Program
{
static void Main()
{
Host.CreateDefaultBuilder()
.ConfigureWebHostDefaults(webHostBuilder => webHostBuilder.Configure(app => app.Run(context => context.Response.WriteAsync("Hello World."))))
.Build()
.Run();
}
}
[ASP.NET Core 3架構揭秘] 跨平台開發體驗: Windows [上篇]
[ASP.NET Core 3架構揭秘] 跨平台開發體驗: Windows [中篇]
[ASP.NET Core 3架構揭秘] 跨平台開發體驗: Windows [下篇]
[ASP.NET Core 3架構揭秘] 跨平台開發體驗: Mac OS
[ASP.NET Core 3架構揭秘] 跨平台開發體驗: Linux
[ASP.NET Core 3架構揭秘] 跨平台開發體驗: Docker
---------------------
作者:
Artech
來源:CNBLOGS
原文:https://www.cnblogs.com/artech/p/inside-asp-net-core-01-02.html
版權聲明:本文為作者原創文章,轉載請附上博文連結!
内容解析By:CSDN,CNBLOG部落格文章一鍵轉載插件