《ASP.NET Core 開發實戰》
========== ========== ==========
[作者] (意) Dino Esposito
[譯者] (中) 趙利通
[出版] 清華大學出版社
[版次] 2019年07月 第1版
[印次] 2019年12月 第2次 印刷
[定價] 79.80元
========== ========== ==========
【前言】
(PVI)
ASP.NET Core 是 ASP.NET 開發人員需要了解的一種技術,是在多種平台上進行 Web 開發時可供使用的另一種全棧解決方案。
【第01章】
(P006)
對於處理必須返回 HTML 內容的 Web 請求, ASP.NET MVC 編程模型是最靈活、最容易理解的方式。
(P008)
.NET Core Framework 主要被設計為用於 ASP.NET 應用程序。
.NET Core Framework 只能用來編寫 ASP.NET 和控制台應用程序。
.NET Core Framework 可與應用程序一同部署,而完整的 .NET Framework 只能安裝到目標機器上,由所有應用程序共享。
(P009)
.NET Core Framework 是從頭開始重新設計的一個新框架,看上去與完整的 .NET Framework 很類似,但是能夠跨平台工作。
(P010)
ASP.NET Core 包含一個內置的 Web 服務器和一個運行應用程序代碼的運行時環境。
【第02章】
(P015)
ASP.NET Core 有一個全新的運行時環境,只支持一種應用模型 : ASP.NET MVC 。
(P018)
一般來說, Web 根文件夾是內容根文件夾的子文件夾,被命名為 wwwroot 。
(P019)
ASP.NET Core 應用程序需要在一個宿主中執行。宿主負責該應用程序的啟動和生命周期管理。
(P021)
事實上, Configure 和 ConfigureServices 方法都是通過反射來發現並調用的。
(P026)
管道由中間件組件構成,這些組件在 Configure 中注冊,對於每個請求,按照注冊的順序調用它們。
(P032)
服務定位器模式更容易添加到現有框架中。依賴注入模式則是從頭構建的框架的理想選擇。
ASP.NET Core 中的 DI 框架並不是完善的 DI 框架,無法與業界頂尖的框架一爭。它只是做一些基本的任務,但做得很好,能滿足 ASP.NET Core 平台的需要。
(P033)
需要重點注意,在 ConfigureServices 中可以注冊外部 DI 框架。不過,在注冊時,必須在啟動類中把方法的返回類型從 void 改為 IServiceProvider 。
只有少數的 DI 框架被移植到了 .NET Core 中,其中包括 Autofac 和 StructureMap 。
要讓自定義代碼在經典 ASP.NET 中運行,最快捷的方法是使用 HTTP 處理程序。
【第03章】
(P053)
在經典 ASP.NET MVC 中,如果沒有找到與 URL 匹配的路由,將得到 HTTP 404 狀態碼。但是,在 ASP.NET Core 中,任何終止中間件都將有機會來處理請求。
【第04章】
(P067)
控制器管理着請求的整個處理過程。
編寫控制器類的步驟可總結為兩個 : 實現一個類,然后在該類中添加一些公有方法,在運行時該類可以作為控制器被發現,而這些方法則可作為操作被發現。
(P068)
MVC 應用程序收到的只是一個待處理的 URL ,這個 URL 必須以某種方式映射到一個控制器類和一個公有方法。
(P069)
傳統路由和特性路由並不是互斥的。二者可用在同一個應用程序中。
特性路由始終是打開的,導致通過特性定義的路由比傳統路由的優先級更高。
只要控制器類的名稱帶有 Controller 后綴,並且繼承自 Controller 基類,就可以被系統發現。
(P070)
操作調用程序將 HTTP 上下文注入控制器實例,在控制器類內運行的代碼可通過 HttpContext 屬性方便地訪問 HTTP 上下文。
(P073)
ASP.NET Core 提供了內置的依賴注入 (DI) 框架,開發人員可通過這個框架來注冊抽象類型 (如接口) 及其具體類型,在請求抽象類型的引用時,返回該抽象類型的具體類型實例的工作則由框架來完成。
(P075)
在 Web 上,當點擊鏈接或者在地址欄中輸入 URL 時,是在執行 HTTP GET 命令。當提交 HTML 表單的內容時,是在執行 HTTP POST 命令。
(P080)
控制器操作方法能夠訪問 HTTP 請求傳遞的任何輸入數據。
(P081)
編寫操作方法體時,可以直接訪問熟悉的 Request 對象及其子類集合 (如 Form 、 Cookies 、 Query 和 Headers) 提交的任何輸入數據。
Request.Query 字典包含從 URL 的查詢字符串提取的參數及其對應值的一個列表。注意,在搜索匹配項時,不考慮大小寫。
(P082)
模型綁定器按精確的順序將參數與傳入的數據匹配起來。它首先檢查是否能夠在路由參數上找到匹配,然后檢查表單提交的數據,最后檢查查詢字符串數據。
(P083)
默認綁定器能夠映射所有的基本類型,如 string 、 int 、 double 、 decimal 、 bool 和 DateTime ,以及這些類型的相關集合。
(P085)
模型綁定器會尋找鍵名稱與屬性名稱匹配的提交值。這種匹配是不區分大小寫的。
(P090)
在 ASP.NET Core 中, Web API 框架 (包括其自己的控制器服務和操作結果類型) 已被集成到主框架中。
【第05章】
(P099)
從架構的角度來看,返回 HTML 標記的請求與返回純本文或 JSON 數據的請求並沒有區別。
(P101)
調用 View 函數將觸發視圖引擎,返回一個對象,該對象封裝了要使用的 Razor 模板文件 (一個擴展名為 .cshtml 的文件) 的名稱和一個視圖模型對象,后者包含了要在最終的 HTML 布局中顯示的數據。
(P102)
視圖引擎是 MVC 應用程序模型的核心組件,負責從視圖創建 HTML 。
在控制器方法內,通過調用 View 方法來調用視圖引擎。
母版頁視圖默認為一個名為 _Layout.cshtml 的 Razor 文件,其 HTML 布局是視圖的基礎。
(P104)
在 ASP.NET Core 中,每個應用程序只有一個默認的視圖引擎 : RazorViewEngine 類。
除了使用 ASP.NET Core 提供的 RazorViewEngine 類,也可以基於自定義語法來實現自己的視圖引擎。
(P105)
使用區域就像是使用多個子應用程序,是將較大的應用程序分區成較小的片段的一種方法。
使用區域時,他們會對路由產生影響。在傳統路由中,區域的名稱是另一個要考慮的參數。
(P110)
Razor 模板文件實際上就是 HTML 模板,其中穿插了一些用 C# 語言 (或者 ASP.NET Core 平台支持的其他任何語言) 編寫的代碼塊。
@符號告訴解析器,在這個位置將發生靜態內容到代碼段的過渡。
(P112)
當多個 Razor 文件起作用時,編譯過程將分步驟進行。首先處理布局模板,然后是 _ViewStart 和實際的視圖。之后合並輸出,這樣 _ViewStart 中的公共代碼將在視圖之前渲染,而視圖則在布局內輸出其內容。
(P113)
控制器向視圖傳遞數據時,最簡單的方法是將信息存入一個 名稱 / 值 字典中。
(P115)
對於使用 ViewData 這樣弱類型的字典,最有說服力的理由是在編程時,它們使用起來簡單快捷。
(P116)
一般來說,在向視圖傳遞數據時,強類型視圖模型是優先選擇的方法。
視圖模型類完全代表了要渲染到視圖的數據。類的結構應該盡可能與視圖的結構匹配。
(P117)
一般來說,應該努力讓每個 Razor 視圖模型有一個專門的視圖模型類。
可以接受把實體模型直接傳遞給視圖的唯一一種情況是確實有一個 CRUD 視圖的時候。但是,坦白講,純粹的 CRUD 視圖如今只存在於教程和總結文章中。
(P118)
在 ASP.NET 中,可以將 DI 系統中注冊的任何類型的實例注入視圖中。這是通過 @inject 指令實現的。
ViewData 字典和 @inject 指令結合起來時,為從 Razor 視圖中獲取需要使用的任何數據提供了一種強大的、極為快速的方法。
(P119)
Razor 頁面就像一個無布局的 Razor 視圖,但是它們使用的根指令是 @page 。Razor 頁面完整支持 Razor 語法,包括 @inject 指令和 C# 語言。
(P120)
需要注意, @page 指令會影響其他支持的指令的行為,所以必須是頁面中的第一條 Razor 指令。
不能將 Razor 頁面放到 Pages 文件夾之外。
【第06章】
(P123)
Razor 文件是一個文本文件,包含兩個主要的語法項 : HTML 表達式和代碼表達式。
(P124)
無論選擇什么編程語言,@ 字符總是表明 Razor 代碼表達式的開始位置。
(P126)
HTML 幫助程序是 HtmlHelper 類的一個擴展方法。抽象來講, HTML 幫助程序只不過是一個 HTML 工廠。
(P127)
xxxFor 幫助程序與基礎版本的區別在於,它只接受一個 Lambda 函數作為參數。
當用來填充視圖的數據被分組到一個模型對象中時, xxFor 版本特別有用。
(P128)
在 Razor 中,布局模板扮演了母版頁的角色。布局模板定義了視圖引擎在任何映射的視圖中渲染的骨架,使得網站的對應部分有了一致的外觀和感覺。
布局模板是一個完整的 HTML 模板,以 <html> 開頭,以 </html> 結束。
(P129)
在任何視圖中,在引用圖片、腳本和樣式表等資源時,都建議使用波浪號運算符 (~) 來指代網站的根目錄。
(P130)
所有布局都強制至少有一個注入點,供注入外部視圖內容。這個注入點就是對方法 RenderBody 的調用。
每個節都通過其名稱標識,如果沒有標記為可選,那么認為每個節都是必須存在的。
(P131)
可以在 Razor 視圖模板的任何位置定義一個節的內容。
【第07章】
(P151)
DI 框架有時也稱為控制反轉 (Inversion-of-Control, IoC) 框架。
DI 框架實際上就是將抽象類型 (通常是一個接口) 映射到一個具體類型。
(P153)
動態解析允許指定一個回調函數來解析依賴。
(P154)
必須調用 IServiceCollection 的某個 AddXxx 擴展方法來把自己的類型添加到 DI 系統中,以及將任何系統抽象類型綁定到不同的實現。
(P164)
要利用好一種強大的技術,最好的辦法就是把這種技術放到業務領域的上下文中。
對於軟件技術,如果沒有合理有效的架構,很難創建復雜的應用程序。
(P165)
在 ASP.NET MVC 應用程序中,表示層由控制器構成,應用層由控制器特定的服務類構成。
(P166)
當一個實體可用於輸入、邏輯、持久化和視圖時,說明處理的應用程序特別簡單。
在 ASP.NET 中,任何輸入數據都被封裝到一個 HTTP 請求中,不管輸入數據來自查詢字符串、表單提交的數據還是 HTTP 頭或 cookie 。
(P167)
建議為每個控制器創建一個服務類,讓控制器的操作方法服從服務類。
服務類中的方法將接受輸入模型中的類,返回視圖模型中的類。
應用層位於表示層和后端之間,進行任何必要的轉換。
當大量使用應用層時,控制器就成為精簡的控制器,因為它們把全部協調工作移交給了應用層。最后,應用層是可以完整測試的,並且完全不知道 HTTP 上下文。
存儲庫是最簡單和最著名的領域服務示例。領域服務類通常會引用數據訪問層。
(P169)
應該把異常處理中間件放到管道的最頂端,以確保能夠檢測到應用程序沒有捕捉的所有可能發生的異常。
(P170)
HTTP 上下文的 Features 對象是獲取未清除的異常信息的官方工具。
ASP.NET Core 的模塊化程度極高,需要使用的幾乎每個功能都必須被顯式啟用。
【第08章】
(P182)
所有聲明都是平等的,但是有一些聲明比其他聲明更加平等。
【第09章】
(P208)
layer 指的是應用程序組件之間的邏輯分離,而 tier 指的是物理上不同的應用程序和服務器。
(P219)
NoSQL 存儲主要用作一種緩存形式,不常用作主數據存儲。
(P221)
EF Core 只支持 Code First 方法,這意味着它需要一組類來描述數據庫和容器表。
【第11章】
(P260)
HTML 表單是由一組 INPUT 元素構成的,當按下某個提交按鈕時,這些 INPUT 元素的值將被流傳輸到一個遠程 URL 。
【第12章】
(P278)
分部視圖不只使結果頁面組件化,加強重用和關注點隔離;而且更容易在客戶端刷新頁面的一部分,而不需要重新加載整個頁面。
【第14章】
(P315)
ASP.NET Core 應用程序本質上是一個獨立的控制台應用程序,它為實際的應用程序模型 (最有可能是 MVC 應用程序模型) 設置宿主環境。
(P324)
對於 ASP.NET Core 2.0 , Kestrel 是最常用的內部 HTTP 服務器。這是一個基於 libuy 的跨平台 Web 服務器,而 libuy 是一個跨平台的異步 I/O 庫。
(P325)
.NET Core 支持的所有平台和版本,都支持 Kestrel 。
(P327)
反向代理將實際的 Web 服務器與來自各種用戶代理的請求完全隔離開。
【第16章】
(P362)
ASP.NET Core 應用程序的跨平台本質是最重要的業務價值。
(P364)
ASP.NET Core 中性能提升的另外一個原因在於其模塊化。
整個 ASP.NET Core 框架以 NuGet 包的形式提供,允許只選擇自己真正需要的功能。