《ASP.NET MVC 5 編程實戰》 - 學習筆記

《ASP.NET MVC 5 編程實戰》

========== ========== ==========
[作者] (美) Dino Esposito
[譯者] (中) 潘麗臣
[出版] 清華大學出版社
[版次] 2015年03月 第1版
[印次] 2015年03月 第1次 印刷
[定價] 59.80元
========== ========== ==========

【前言】 

Web Forms 的最常見應用場景是,你要開發專注於呈現數據並使用第三方控件套裝的應用程序。

ASP.NET MVC 可用於處理其他所有方面,包括客戶端單頁面應用程序的框架搭建。

ASP.NET MVC 足以成爲任何一個需要實體後臺的應用程序的理想 Web 平臺,對於那些以多設備實用功能爲目標的 Web 應用程序來說尤其如此。

【第01章】 

(P003) 

在 ASP.NET MVC 中,每個請求的結果最終都會執行某個操作 —— 根本上來說也就是特定類上的方法。操作執行的結果會與一個視圖模板一起傳遞給視圖子系統。結果和模板隨後會用於生成瀏覽器的最終響應。用戶不需要將瀏覽器指向某個頁面,他們只需要放置一個請求即可。

使用 ASP.NET MVC ,可以獲得對標記的完全控制,並能隨意用你最喜歡的 JavaScript 框架來套用樣式和注入腳本代碼。

(P004) 

在軟件中,術語 URI (統一資源標識符) 是指通過一個位置或一個名稱來引用資源。

當 URI 通過位置識別資源時,它被稱爲 URL 或統一資源定位符。

當 URI 通過名稱識別資源時,它就成爲一個 URN 或統一資源名稱。

(P005) 

在 ASP.NET 中, HTTP 處理程序是一個實現了 IHttpHandler 接口的組件。

HTTP 處理程序可以解析出令牌中的 URL ,並使用該信息來標識要調用的類和方法。

(P007) 

處理請求的專門組件是控制器。控制器是一個只有方法而無狀態的類。

獨特的系統級 HTTP 處理程序負責將傳入的請求分派到一個專門的控制器類,這樣該類的實例就會執行給定的操作方法併產生響應。

URL 路由 HTTP 模塊通過查看 URL 並把它們分派到最適當的執行器來處理傳入的請求。 URL 路由 HTTP 模塊取代了舊版本 ASP.NET 的 URL 重寫功能、在其核心處, URL 重寫由掛接請求、解析原始 URL 和指示 HTTP 運行時環境組成,用以處理 “可能相關卻不同” 的 URL 。

(P008) 

URL 重寫確實可以將處理該請求的物理網頁與所需的 URL 進行解耦。

在 ASP.NET MVC 中, URL 路由提供了把傳入的 URL 映射到控制器類和操作方法的服務。

URL 路由模塊最初是作爲 ASP.NET MVC 組件來開發的,而現在成爲 ASP.NET 平臺的一個原生部分,且如前所述,它能夠同時爲 ASP.NET MVC 和 ASP.NET Web Forms 應用程序提供服務,雖然是通過略微不同的 API 。

只有與預定義 URL 模式 (也稱爲路由) 相匹配的請求才能享有 ASP.NET MVC 運行時。所有這類請求會被路由到一個共同的 HTTP 處理程序,該處理程序將控制器類實例化並調用該類中一個定義了的方法。接下來,控制器方法會進而選擇視圖組件生成實際的響應。

(P009) 

在 ASP.NET MVC 中實現一個純粹的 REST 解決方案是可能的,但需要做一些額外工作。

(P010) 

應用程序路由通常在 Global.asax 文件中註冊,並在應用程序啓動時得到處理。

(P011) 

RegisterRoutes 是一個在通常命名爲 APP_Start (但可以隨意重命名該文件夾) 的單獨文件夾中所定義的 RouteConfig 類的方法。

所支持的路由必須添加到由 ASP.NET MVC 管理的路由對象的靜態集合中。該集合就是 RouteTable.Routes 。

(P012) 

爲確保按正確順序處理該路由,必須將它們按照從最具體到最不具體的順序羅列出來。

(P014) 

默認情況下, ASP.NET 路由系統會忽略那些其 URL 可以映射到實際存在於服務器上的文件的請求。請注意,如果服務器文件存在,則路由系統將忽略該請求,即使請求匹配了路由。

(P015) 

通過 URL 路由篩選器的任何請求都被映射到一個控制器類,通過執行類上的給定方法來進行服務。

常見的做法包括爲應用程序所實現的每個重要功能配備一個控制器類。

(P017) 

控制器類的編寫可以概括爲兩個簡單的步驟 : 第一,創建從 Controller 繼承 (直接或間接均可) 而來的類;第二,添加一系列的公共方法。然而,必須闡明兩個重要的細節 : 系統如何獲知控制器類要實例化,以及它如何確定要調用的方法。

不論如何定義 URL 模式,任何請求都必須根據控制器名稱和操作名稱來解析。這是 ASP.NET MVC 的一個支柱。如果 URL 包含了一個 {controller} 佔位符,那麼控制器名稱會自動從 URL 中讀取。如果 URL 包含了 {action} 佔位符,那麼操作名稱也將從 URL 中自動讀取。

(P020) 

將特定動詞分配到給定的操作方法的能力很自然地會導致重複的方法名稱。具有相同名稱的兩種方法在控制器類中都可以被接受,只要它們接受不同的 HTTP 動詞。否則,將引發異常,因爲 ASP.NET MVC 不知道如何解析一詞多義的情況。

還可以使用多個單獨的特性,每個特性用於一個 HTTP 動詞。
 
(P021) 

容器對象通常也稱爲視圖模型,可以是一對 名稱 / 值 的淺顯字典,或者是特定的視圖強類型類。

(P022) 

控制器操作方法可以訪問任何通過使用 HTTP 請求而提交的輸入數據。輸入數據可以從各種來源檢索,包括表單數據、查詢字符串、 Cookies 、路由值和提交文件。

在編寫操作方法的主體時,當然可以訪問傳給 Request 對象及其子集的任何數據,這些 Request 對象及子集包括 Form 、 Cookies 、 ServerVariables 和 QueryString 。

在 ASP.NET 中, Request.Params 字典產生於四個不同字典的組合,即 QueryString 、 Form 、 Cookies 和 ServerVariables 。也可以使用 Request 對象的 Item 索引器屬性,它會提供一樣的功能,並按一下順序在字典中搜索匹配項 : QueryString 、 Form 、 Cookies 和 ServerVariables 。

(P028) 

ActionResult 類的最終目的是準備好要返回到瀏覽器的 HttpResponse 對象。

在 ASP.NET Web Forms 中,構成 HTML 的任務是通過頁面完成的。開發人員創建 ASPX 頁面作爲視圖模板和代碼隱藏類的混合容器。抓取結果的操作與實際響應的產生,這兩者在單一的運行時環境中是難以分開的。

在 ASP.NET MVC 中,產生出結果是操作方法的責任;管理響應的構成和服務則是框架的責任。而最後,構成 HTML 標記更是另一個系統組件 —— 視圖引擎 —— 的責任。

視圖引擎規定了視圖模板的語法 (比如 ASPX 、 Razor 和 Spark) ;而由開發人員決定合併到視圖的原始數據格式。

(P029) 

視圖模板文件的擴展名也取決於視圖引擎的實現。對於 ASP.NET MVC 中的兩個預定義的視圖引擎來說,如果選擇 ASPX 視圖引擎,那麼擴展名爲 .aspx ;如果選擇 Razor 視圖引擎,則擴展名爲 .cshtml (或 .vbhtml) 。

ASP.NET MVC 非常適合實現那些會從 Ajax 上下文的 jQuery 代碼片段中回調的簡單 Web 服務。只需設置一個或多個操作方法,以返回 JSON 字符串而不是 HTML 。

Json 幫助器方法可以獲取一個普通的 .NET 對象,並使用內置的 JavaScriptSerializer 類將它序列化爲字符串。

ASP.NET MVC 會將任何從操作方法返回的值 (數字、字符串或自定義對象) 封裝成一個 ContentResult 對象。

ContentResult 對象的執行會導致瀏覽器中值的序列化。

空白返回值實際上是被映射到了 EmptyResult 對象,而它的執行不會觸發任何操作。

(P030) 

控制器的主要目的是服務於用戶界面的需要。需要執行的任何服務器端函數都要映射到一個控制器方法並從用戶界面觸發。執行完自己的任務後,控制器方法會選擇下一個視圖、封裝一些數據並指示數據的提交。

(P031) 

請記住,在 ASP.NET MVC 中,解決方案建築中的任何分層都取決於你。

【第02章】 

(P033) 

在 ASP.NET MVC 中,只需要處理兩種主要類型的組件。一種是控制器,它負責執行請求併爲原始輸入生成原始結果。另一種是視圖引擎,它負責生成基於由控制器計算出的結果的任何預期的 HTML 響應。

可以把 ASP.NET MVC 應用程序看作是能夠服務於各種響應的組件集合,這些響應包括 HTML 、 JavaScript 、 JavaScript 對象標誌 (JSON) 和純文本。

(P034) 

視圖引擎是爲瀏覽器實際生成 HTML 輸出的組件。視圖引擎負責爲每個請求返回 HTML ,並且它通過將視圖模板和由控制器傳遞進來的數據進行融合來準備其輸出。該模板以一種引擎專用的標記語言來表示;其數據在字典或強類型對象中進行封裝傳遞。

在 ASP.NET MVC 中,視圖引擎只是一個實現固定接口 —— IViewEngine 接口的類。每個應用程序可以有一個或多個視圖引擎。在 ASP.NET MVC 5 中,每個應用程序默認配備兩個視圖引擎。

(P035) 

ViewEngines 類是跟蹤當前已安裝引擎的系統資源庫。

(P036) 

最可能面臨使用 ViewEngines.Engines 的情況是當需要添加一個新的視圖引擎或卸載現有視圖引擎的時候。這需要在應用程序啓動時進行,更準確地說,是在 Global.asax 裏的 Application_Start 事件中。

(P037) 

控制器和視圖引擎的活動都由一個外部的管理器對象 (操作調用程序) 進行協調。

(P038) 

控制器類上的 View 方法會將幾段數據一起封裝進一個單獨的容器 : ViewResult 類中。

視圖的名稱是控制器操作上 View 方法應該提供的參數之一。如果程序員沒有顯式定義這樣的參數,則系統會按照慣例假定視圖名稱與操作名稱相同。

(P040) 

視圖引擎的調用會依照它們的註冊順序,並且在默認情況下, ASPX 引擎會優先於 Razor 引擎。若要修改這一順序,需要在應用程序啓動時清除引擎集合,再重新按喜歡的順序添加引擎。

(P041) 

視圖無非是用來生成 HTML 內容的模板。

(P042) 

在 ASP.NET MVC 中,把需要傳遞到視圖的數據在一個容器對象中進行分組,再將該容器對象作爲選擇了該視圖的控制器調用中的參數進行傳遞。

ASP.NET MVC 使你能夠在對 View 方法的調用中直接傳遞容器對象。在任何情況下,都有兩個預定義的字典可用於控制器方法填充數據。它們分別是 ViewData 字典和 ViewBag 字典。

需要記住的是,在理想的情況下,視圖對象不需要自行檢索數據;它必須處理的唯一數據只是從控制器所接收的數據。

指定母版視圖是比較容易的。可以使用視圖引擎所支持的規則,也可以在從控制器中選擇下一個視圖時將母版視圖的名稱作爲參數傳遞給 View 方法。

(P043) 

在 ASP.NET MVC 中等同於 服務器控件的技術是什麼?答案就是 HTML 幫助器。

HTML 幫助器就是簡單的 HTML 工廠。

HTML 幫助器的內部機制就是將文本累加到一個 StringBuilder 對象中。

(P044) 

每個 HTML 幫助器均有一大堆重載來指定特性值和其他相關信息。

一個形如 xxxFor 的幫助器與基礎版本的不同之處在於它只接受 lambda 表達式。

(P045) 

默認情況下, BeginForm 會呈現一個回發到相同 URL 並隨後回發相同控制器操作的表單。

使用 BeginForm 方法的其他重載,可以指定目標控制器的名稱和操作、該操作的任意路由值、 HTML 特性,甚至可以指定是否需要表單執行 GET 或 POST 動作。

BeginRouteForm 的作用與 BeginForm 差不多,但有一點不同,它可以從任意一組路由參數開始而生成一個 URL 。換句話說, BeginRouteForm 並不侷限於基於控制器名稱和操作的默認路由。

(P046) 

能在表單中使用的所有 HTML 元素都有一個 HTML 幫助器來加速開發。

從功能的角度來看使用幫助器與使用普通的 HTML 之間並無差別。

擁有將驗證消息與輸入字段相關聯的工具。如果指定的字段中包含錯誤,則可以使用 Html.ValidatiobnMessage 幫助器來顯示驗證信息。該消息可以通過幫助器的一個附加參數顯式指示出來。所有的驗證消息之後會通過 Html.ValidationSummary 幫助器聚合與顯示出來。

(P047) 

ActionLink 幫助器是 ASP.NET MVC 視圖中最常用到的一個。

通常情況下,操作鏈接需要鏈接文本、操作名稱和可選的控制器名稱。

RouteLink 幫助器的工作方式差不多相同,但它不需要指定操作。有了 RouteLink 幫助器,就可以使用任何已註冊的路由名稱來確定生成的 URL 的模式了。

若要生成基於控制器和操作數據的鏈接,則可以使用 UrlHelper 類。

UrlHelper 類有幾個方法的作用類似於 ActionLink 和 RouteLink 。它們的名稱是 Action 和 RouteUrl 。

(P048) 

可以使用 Partial 或 RenderPartial 幫助器方法來插入一個部分視圖。這兩種方法都採用該部分視圖的名稱作爲參數。兩者的唯一區別是 Partial 返回一個字符串,而 RenderPartial 會寫入到輸出流,並返回空。因此,兩者的用法稍有不同。

部分視圖包含在視圖中,但會被視作完全獨立的實體。

爲一個視圖引擎編寫一個視圖而該視圖的部分視圖卻需要另一個視圖引擎的情形是完全合理的。

(P049) 

有了模板化幫助器,就不會失去對用戶界面的控制了;簡言之,模型中的特性建立起一系列的規則,將你從繁重的重複勞動中解放了出來。

在 ASP.NET MVC 中,有兩個基本的模板化幫助器 : Editor 和 Display 。

ViewBag 是在被定義爲動態類型的 ControllerBase 類上定義的屬性。

(P050) 

lambda 表達式不支持動態成員,因此不能用於將數據傳遞到 ViewBag 字典。

Editor 幫助器的目的是讓你編輯指定值或對象、該編輯器會識別它所獲取的值的類型,並挑選量身定做的模板進行編輯。

Editor 幫助器極其擅長處理複雜類型。它通常會遍歷每一個公共屬性,併爲子值建立一個標籤和編輯器。

(P051) 

TagBuilder 類生成 HTML 標記的文本,從而可以通過串聯標籤而非普通的字符串以構建大塊的 HTML 。

HTML 幫助器預期會返回一個已編碼的 HTML 字符串。

(P052) 

所有的原生 HTML 幫助器都會被重構以返回 MvcHtmlString 。

MvcHtmlString 類型是對包含 HTML 內容的字符串的一個智能封裝,它公開了 IHtmlString 接口。

IHtmlString 的目的是什麼?在 ASP.NET 中試圖對實現 IHtmlString 的對象進行 HTML 編碼會造成空操作指令。

(P054) 

根據 Razor ,視圖模板就是一個 HTML 頁面加上幾個佔位符和代碼片段。

(P056) 

Razor 視圖模板實質上是一個 HTML 頁面加上幾個代碼段,也稱爲代碼碎塊。

Razor 代碼塊的標誌是開頭使用 @ 字符。更爲重要的是,不需要顯式關閉這些代碼塊。

(P057) 

Razor 模板就是帶有封裝了可執行語句和 HTML 幫助器的 @ 表達式的普通 HTML 標記文件。

可以通過在 @{code} 塊中進行封裝來在任意位置插入整段的多行代碼。

(P058) 

來源於表達式的單個語句可以通過使用括號在同一表達式中組合。

在你需要放置一個函數調用時,括號也起作用。

(P059) 

Razor 視圖引擎在使用時,生成的視圖對象是一個在 System.Web.Mvc 程序集中定義的 WebViewPage 類的實例。這個類集成了解析標記和呈現 HTML 的邏輯。該類上的公共屬性對於在實際模板中編寫的任何代碼碎片都可用。

(P060) 

控制器能以各種方式將數據傳遞給視圖。它可以使用全局字典,如 ViewBag 或 ViewData 。更好的是,控制器可以使用爲特定視圖量身定做的強類型對象。

要從代碼碎塊中使用 ViewBag 或 ViewData ,不需要採取任何特別措施。只需要編寫讀入或寫進字典的 @ 表達式即可。相反,要使用強類型的視圖模型,需要在模板文件的頂部聲明實際的類型。

通過使用 Model 屬性訪問視圖模型對象中的屬性。

如果 Model 引用了具有子屬性的對象,那麼可以使用 Model.Xxx 來引用每個子屬性。

在 Razor 中,佈局頁面扮演着 Web Forms 中母版頁的角色。佈局頁面是一個標準的 Razor 模板,視圖引擎會將定義的任意視圖呈現出來,從而將外觀和感覺與網站版面統一起來。

(P061) 

使用 Razor ,可以在 Views 文件夾中定義一個特殊文件,該文件在每個視圖構建和呈現之前進行處理。這個文件被稱爲 _ViewStart.cshtml ,是任何與視圖相關的啓動代碼的理想容器,其中包括決定使用哪個佈局的代碼。

執行 RenderBody 方法會導致實際視圖中的任何代碼都注入佈局模板。

實際視圖模板中的代碼會在視圖和佈局合併之前進行處理。

(P062) 

從 ASP.NET MVC 4 開始,波浪號 (~) 通過 Razor 引擎自動擴展,雖然 Url.Content 的使用依然受到支持,但已不再必要。

在佈局模板中,通過在希望節所出現的位置放置一個對 RenderSection 的調用來定義注入點。

每一個節都由名稱標識,並能標記爲可選。

如果視圖模板不包含所需的節,會得到一個運行時異常。

(P063) 

可以在 Razor 視圖模板的任何位置定義節的內容。

WebViewPage 類提供了一個方便的 IsSectionDefined 方法,可以用在 Razor 模板中確定給定的內容是否已被指定。

請記住節的名稱不區分大小寫。

可以對 Razor 佈局進行任意程度的嵌套。

(P066) 

ASP.NET MVC 設計的黃金法則聲明,視圖會接收但不會計算它要顯示的任何數據。可以通過三種非獨佔性的方式傳遞數據 : ViewData 字典、 ViewBag 字典以及量身定做的容器對象,也常被稱作視圖模型對象。

ViewData 屬性直接由 Controller 類公開,它是 名稱-值 字典對象。其編程模型類似於使用 Session 或其他 ASP.NET 內部對象。

存儲在字典中的任何數據都會被當作一個對象來處理,需要轉換、裝箱、或這兩者一起以便被視圖所用。可以按需在字典中創建條目。字典的生存週期與請求的生存週期是一樣的。

請記住,不會被限於僅在 ViewData 字典中存儲字符串。

ViewData 字典非常適合於簡單的解決方案和相對較短生命週期的應用程序。隨着字典條目數量和視圖數量的增長,維護會成爲一個問題,因此尋找其他選項時應該擺脫 ViewData 。

(P067) 

ViewBag 屬性也在 Controller 類上進行定義,它提供了一個更加靈活的將數據傳遞給視圖的工具。

基於動態類型的任何表達式都會被編譯成在運行時解釋。

ViewBag 的語法比 ViewData 的語法更爲簡潔,但就我看來,這就是所有的區別了。

ViewBag 至少需要是 ASP.NET MVC 3 和 .NET 4 ,而 ViewData 的適用範圍是 ASP.NET MVC 的任何版本和 .NET 2.0 。

(P068) 

處理軟件中複雜性的唯一證明有效的方法是合適的設計。

爲每個視圖定義一個對象模型可以幫助跟蹤視圖的真實所需。建議爲每一個添加到應用程序中的視圖定義一個視圖模型類。

視圖模型對象是一個只有數據而 (幾乎) 沒有行爲的普通數據傳輸對象。

(P069) 

ASP.NET MVC 基礎架構保證了 ViewData 和 ViewBag 始終可用於視圖對象而無需開發人員的任何干預。而自定義視圖模型對象就不是這樣了。

當使用一個視圖模型對象時,必須在視圖模板中聲明該視圖模型類型。

要在視圖模板中檢索視圖模型對象,可以使用在 WebViewPage 和 ViewPage 上都定義過的 Model 屬性。

(P070) 

雖然每個視圖都應該有自己的模型對象,但限制要處理的類的數量通常是一個好選擇。要在多個視圖中重用模型類,往往需要生成一個類的層次體系。

視圖模型類最終是爲視圖建模而不是爲數據。

對於至少中等複雜程度和中等持續時間的任何 ASP.NET MVC 應用程序來說,強類型視圖模型是唯一安全而可行的解決方法。

【第03章】 

(P075) 

通常存在至少兩種完全不同的模型 : 領域模型和視圖模型。

“領域模型” 描述在中間層使用的數據,預期會爲填充業務領域的實體和關係提供可靠的表示。這些實體一般通過數據訪問層來持久保存,並且通過實現業務流程的服務來使用。

視圖模型只描述了表示層中正在處理的數據。

應該始終意識到在兩個不同層中運行着兩種不同模型的事實。

(P076) 

要將輸入數據傳遞給控制器,需要以某種方式把數據封裝起來。

(P078) 

輸入模型提供了正在提交到控制器的數據的表示。視圖模型提供了正在視圖中進行處理的數據的表示。最後,域模型是在中間層中操作的域特定實體的表示。

類的最終結構和關係圖取決於你自己。

模型綁定是指將通過 HTTP 請求所提交的值綁定到控制器方法所用的參數的過程。

(P079) 

默認模型綁定器使用基於規則的邏輯,將提交的值的名稱與控制器方法中的參數名稱相匹配。

默認模型綁定器會使用所有已註冊的值提供程序將提交值與方法參數進行匹配。

可以在方法簽名上列出的參數的數目沒有上限。但是,一個容器類往往比一個各種參數的長列表要好。對於默認模型綁定器,無論列出一系列參數,還是複雜類型的一個參數,結果幾乎相同。這兩種方案都完全受到支持。

(P083) 

模型綁定器能夠處理該複雜類型,就像它處理單個值的情況一樣。

對於聲明的類型中的每一個公共屬性,模型綁定器都會尋找其關鍵字名稱與屬性名稱相匹配的提交值。匹配不區分大小寫。

(P089) 

默認綁定器通過匹配與參數名稱一起上傳的輸入文件元素的名稱來實現綁定。但是參數 (或參數類型上的屬性) 必須聲明爲 HttpPostedFileBase 類型。

(P090) 

默認情況下,任何 ASP.NET 請求都不能超過 4MB 。這個數字包含了所有的上傳、標頭、正文以及正在傳輸的任何內容。可以通過 web.config 文件中 httpRuntime 部分的 maxRequestLength 條目來配置各個級別的上傳閾值。

(P092) 

默認的模型綁定器會強制將請求參數命名爲在目標操作方法上與形參相匹配的指定名稱。

(P095) 

請記住,編寫模型綁定器時,並不侷限於僅從提交數據中獲取用於模型的信息,雖然這代表了大多數常見情形。可以從任何位置 (比如從 ASP.NET 緩存和會話狀態中) 獲取信息,解析並將它存儲在模型中。

(P096) 

局部綁定器總是優先於全局定義綁定器。

(P102) 

模型綁定器提供了將表單提交值反序列化爲簡單類型和複雜類型的完全控制權。

【第04章】 

(P103) 

HTML 幫助器,可以自動爲任何簡單或複雜的類型創建簡單而實用的視圖和編輯器。

數據批註,可以用聲明方式設置對某字段的內容及其顯示行爲的預期。

模型綁定器,可以將提交的值序列化爲對服務器端的處理更爲適用的對象。

(P112) 

PRG 模式建議每個 POST 請求在經過處理後,以重定向到一個通過 GET 訪問的資源而結束。

(P117) 

在 ASP.NET MVC 中,模板化幫助器使用與類成員相關聯的元數據來決定如何顯示或編輯數據。元數據通過元數據提供程序對象讀取;默認的元數據提供程序會從數據批註特性中獲取信息。

(P118) 

數據批註是特性,而特性通常不包含代碼。它們僅僅表示其他模塊需要使用的元信息。通過使用數據批註,模型對象就被元數據修飾了。這並不能預計產生任何的可見影響 : 一切都取決於其他組件如何使用元數據。

數據批註包括描述性特性和驗證特性,描述性特性指示偵聽器如何顯示或編輯數據,驗證特性指示偵聽器如何驗證模型類的內容。

(P119) 

注意如果沒有使用 DisplayForModel 或 EditorForModel 自動生成輸入表單,就不需要數據批註。

(P122) 

顯示 / 編輯 幫助器在很大程度上可以自定義。任何自定義的模板都包含一個位於 Views\[Controller]\DisplayTemplates 文件夾用於顯示幫助器的自定義視圖,和一個位於 Views\[Controller]\EditorTemplates 文件夾用於編輯幫助器的自定義視圖。

(P141) 

當開啓客戶端驗證時,所有內置的數據批註特性都會獲得一個客戶端行爲,並儘可能在瀏覽器中執行其在 JavaScript 中的驗證。如果驗證失敗,就不會向 Web 服務器發出請求。

【第05章】 

(P151) 

在很大程度上,可以把 ASP.NET MVC 視爲經典 ASP.NET 運行時環境的特別版本,其僅用於支持不同的應用程序和編程模型。

ASP.NET MVC 應用程序對構成 ASP.NET 生態系統的任何內置組件都具有完全訪問權,包括 Cache 、 Session 、 Response ,以及身份驗證和錯誤處理層。

(P152) 

HttpResponse 對象的公共接口可以設置 cookies 和內容類型、附加標頭、以及針對響應數據的緩存將指令傳遞給瀏覽器。另外, HttpResponse 對象還有助於重定向到其他 URL 。

在 ASP.NET 中,當調用 Response.Redirect 時,會向瀏覽器返回一個 HTTP 302 代碼,表明所請求的內容現在可以從另一個指定位置獲得。

(P155) 

ASP.NET MVC 基礎架構在內部使用會話狀態,也可以在代碼中這樣做。

(P156) 

ASP.NET MVC 基礎架構會使用會話狀態來保持 TempData 字典的內容。

在會話狀態中存儲的任何數據都會作爲一個 Object 返回。

(P157) 

在 ASP.NET 中,內置的緩存功能是通過 Cache 對象實現的。 Cache 對象是在每一個 AppDomain 基礎上創建的,並且在 AppDomain 運行期間它仍然保持有效。

(P161) 

MemoryCache 類繼承自基類 ObjectCache 。通過派生你自己的緩存對象,可以控制內部存儲以及緩存數據的管理。

請記住, ObjectCache 及其派生的類型並不適用於提供分佈式緩存功能。

(P165) 

來自微軟的關於異常處理的另一項主要原則是,對於一般的錯誤使用內置類型,對於特定於你正在創建的應用程序,要創建應用程序專屬的異常類型。

(P171) 

在 ASP.NET 開發人員之間比較流行的工具是錯誤日誌記錄模塊和處理程序 (Error Logging Modules And Handlers , ELMAH) 。 ELMAH 本質上是由一個 HTTP 模塊構成,一旦配置,就會攔截應用程序級別的 Error 事件,並根據大量後端存儲庫的配置將其記錄下來。

當自定義錯誤標誌關閉時,攔截模型綁定錯誤的唯一辦法就只能是藉助於 Global.asax 中的集中式錯誤處理程序。

(P173) 

全部捕獲規則需要在路由列表的最底部運行。

在 ASP.NET MVC 中並沒有現成的 Error 控制器,但強烈建議創建一個。

(P174) 

通過使用錯誤控制器,可以提高應用程序的友好性,併爲搜索引擎對其進行優化。

全部捕獲路由就是一個爲 URL 選出的不匹配任何其他路由的路由。

(P181) 

在 ASP.NET MVC 中,當你只想呈現視圖的時候要使用 Html.RenderPartial ;當你想要取回 HTML 標記並自己編寫到流時,要使用 Html.Partial 。

【第06章】 

(P190) 

Windows 身份驗證很少應用於實際的互聯網應用程序。

表單身份驗證是最常用的收集和驗證用戶憑據的方式,例如使用用戶賬戶數據庫進行驗證。

在 ASP.NET MVC 和 Web Forms 中,是通過根 web.config 文件中的 <authentication> 部分選擇身份驗證機制的。

默認情況下, ASP.NET MVC 應用程序會被配置爲使用 Forms 身份驗證。

當要限制對某操作方法的訪問時,請使用 Authorize 特性,並確保只有通過身份驗證的用戶可以執行它。

如果將 Authorize 特性添加到控制器類,那麼控制器上的任何操作方法都將需要進行身份驗證。

(P191) 

絕對不要將 Authorzie 特性用作全局篩選器。

AllowAnonymous 方法派上用場的情況是,當把 Authorzie 應用在類級別時,之後需要啓用對一些方法的自由訪問,尤其是登錄方法。

【第07章】 

(P231) 

工作線程服務或應用程序服務屬於系統的應用程序層,應用程序層是實現從用例中所產生的應用程序邏輯的地方。這一層不能重用,因爲它是特定於應用程序 (和前端) 的。可重用性要推至下一層的域層中。意即核心功能是可重用的 (也就是域) ,但呈現工作流會特定於應用程序。

ASP.NET MVC 是一個旨在方便測試和推動像關注點分離 (SoC) 和依賴注入 (DI) 這樣的重要原則的框架。

(P239) 

層 (layer) 是指邏輯上的分離,而層級 (tier) 是指物理上的分離。

(P240) 

表示層截獲請求並將其傳遞到應用程序層。應用程序層 (也稱爲服務層) 是應用程序實現用例的區段。在這一點上,它特定於每個應用程序並且不可重用。應用程序層將端點公開給表示層,並將它從系統的其他部分解耦。應用程序層會安排域服務和外部服務,以及可能用到的特定業務的企業組件。最後,基礎架構層會封裝對數據的訪問。

(P241) 

就 ASP.NET MVC 而言,應用分層架構模式意味着將請求的響應結果委託給工作線程服務,接着,會聯繫後端獲得響應。響應包含了表示層所需格式的數據。

應用程序層包含用例的實現,可以將其看作起編排作用的組件的聚合。

(P242) 

對象模型、域模型和實體模型是常常可以互換使用的相似術語。

對象模型是普通、泛型的對象集合。

域模型是特殊類型的對象模型,其中的每一個類都是 POCO 、聚合根會被識別出、工廠會被用於構造函數、並且大多數時候值類型往往會取代基元類型。

實體模型基本上是一個表明類 (大多是貧血類) 的集合的實體框架術語。可能是 POCO ,也可能不是。貧血類有數據,但幾乎沒有行爲。

(P243) 

專注於視圖的對象模型是基於數據傳輸對象 (data-transfer objects , DTO) 的。 DTO 是一個普通的容器類 (只有數據,沒有行爲) ,用於在層、層級之間甚至同一層之內傳遞數據。

基礎架構層基本上就是數據庫層,重命名後降低了放在數據和模型上的焦點和重點。

(P244) 

基礎架構層處理持久性,它由存儲庫類構成,每個重要實體 (或者,也可以稱爲聚合根) 配有一個。存儲庫類使用一個指定的存儲 API 來實現持久性。存儲庫類的實現在邏輯上屬於數據訪問層。存儲庫類會聚集多個服務於實體數據訪問需求的方法。在存儲庫中,通常可以找到讀取、添加、刪除和更新數據的方法。

存儲庫嚮應用程序層公開接口並在內部使用存儲 API 。

在每個實體的基礎上 (確切地說,只是主要實體) 創建的存儲庫是通往實際持久層的大門。

(P245) 

高級別的類應該總是依賴於它們所需低級別類的抽象。

(P246) 

服務定位器模式定義了一個組件,它知道如何檢索應用程序可能需要的服務。調用方無須指定具體的類型;調用方通常表示接口、基類型或者是以字符串或數字編碼形式存在的服務暱稱。

(P247) 

依賴注入模式表明你要以這樣一種方式設計類 : 它從外部接收其所有依賴性。

(P248) 

在類中使用依賴注入的時候,開發人員必須作出的一個關鍵決定是,如何以及在何處讓代碼注入。有三種方式可以把依賴性注入到類中 : 使用構造函數、一個可設置的屬性、或一個方法的參數。這三種方式都有效,最終的選擇取決於你。一般的共識是將構造函數用於必要的依賴性, setter 方法用於可選的依賴性。

(P249) 

IoC 容器是一個專門創建用來支持 DI 的框架。

【第08章】 

(P257) 

TempData 字典用來存儲從邏輯上講屬於當前請求的數據,但必須要跨越一個重定向來使用。

根據 PRG 模式,應該用一個 GET 重定向到顯示結果的視圖來終止一個 POST 請求。

默認情況下, TempData 字典會將其內容保存到會話狀態。直接使用 Session 與藉助 TempData 的主要區別是,任何存儲在 TempData 中的數據都會在連續請求終止後自動清除。換句話說,數據駐留在內存中只會用於兩個請求 : 當前請求和下一個重定向。歸根結底, TempData 帶給內存的壓力更小。

(P260) 

對於從頭開始構建的新系統, DI 是該優先考慮的;它會使代碼保持得更整潔,更便於閱讀和測試。使用 DI ,依賴性在類的簽名中是顯式的。不過,周邊框架要求對依賴性的準備和注入負完全責任。對於現有系統, SL 更容易接入使用,因爲它只會要求你將調用封裝在一個公開接口的黑盒中。

(P261) 

單獨註冊的組件對應用程序來說一定是唯一的一個組件。多次註冊的組件可以註冊多個實例並向系統的其他部分公開。

(P266) 

每個控制器方法可以用多個篩選器來修飾。

可以把篩選器應用於單個方法,也可以應用於整個控制器類。如果將篩選器應用於控制器類,則會對所有由控制器公開的操作方法產生影響。與此相反的是,全局過濾器是在應用程序啓動時註冊並自動應用於任何控制器類的任何操作。

(P268) 

在 ASP.NET Forms 中,壓縮一般是通過 HTTP 模塊攔截請求和壓縮響應來實現的。你還可以在互聯網信息服務 (IIS) 級別開啓壓縮。這兩個選項在 ASP.NET MVC 中都好用,決定使用哪一個選項取決於你。

ASP.NET MVC 提供了特別容易實現的第三個選項 : 一個對壓縮事件進行設置的特定操作篩選器。用這種方式,可以在不必編寫 HTTP 模塊的情況下控制某種特定的 URL 。

【第09章】 

(P305) 

從設計的角度看,可測試軟件本質上是更好的軟件。

當你把控制性、可見性和簡單性應用於軟件開發過程中時,最終會獲得只通過約定接口就能進行交互的相對較小的構建塊。

(P307) 

指示你的類面向接口運行而不是面向實現運行是現代軟件開發的五大支柱之一。

開發的五項原則常常被總結爲首字母縮寫的 SOLID 一詞。

(P308) 

在現代軟件中,編寫面向接口而非面向實現的代碼這一概念已被廣爲接受和應用了,但它也常常被另一個更具體的概念所掩蓋 : 依賴注入。

可以說基於接口編程的整個概念是在依賴反轉原則 (DIP) 中進行硬編碼,且依賴注入是應用 DIP 的一種流行設計模式。

(P313) 

測試方法的典型設計可總結爲三個縮寫的 “A” ,分別代表着設置、作用、斷言。

【第10章】 

(P339) 

ASP.NET Web API 是一個新的框架,其明確意圖是支持和簡化可以由各種客戶端所使用的 HTTP 服務的構建過程;尤其是 HTML 網頁和移動應用程序。

Web API 是一個精心設計的框架,它用於爲 .NET 應用程序構建 RESTful (具象狀態傳輸) 和遠程過程調用 (RPC) 風格 HTTP 服務。

(P340) 

WCF 的最初構想是透過種類繁多的傳輸層來支持 SOAP 和 WS-* ,這些傳輸層包括 TCP 、 消息隊列 (MSMQ) 、命名通道,以及最後也是最重要的一個 : HTTP 。

(P341) 

Web API 非常適合於現在似乎常見的應用程序場景 : 客戶端應用程序需要調用遠程後端來下載數據或請求處理。客戶端應用程序可以採用多種形式 : JavaScript 密集型網頁、富客戶端或移動應用程序。

JSON 格式是在客戶端和 HTTP 服務之間序列化對象的理想格式。

(P343) 

Web API 基礎架構與 ASP.NET MVC 基礎架構是獨立的,不具有隱藏的依賴性。

(P344) 

Web API 模塊是一個獨立的基於 HTTP 的服務,能夠被許多應用程序託管,而 ASP.NET MVC 應用程序大概是最常用的宿主類型。

REST 被定義爲專注於通過 Web 協議、特別是 HTTP 協議識別和處理資源的一種架構風格。

(P351) 

構建一個在 ASP.NET MVC 應用程序內部的 Web API 模塊是由該 ASP.NET MVC 應用程序託管的。

要使用 Web API 模塊,你只需要使用 ASP.NET MVC 站點即可。

從 Web 客戶端內部, Web API 前端就是一個簡單的 HTTP 端點集合。可以使用 jQuery 工具來放置 HTTP 調用,或者使用 KnockoutJS 工具來呈現出對象集合。

(P352) 

$.ajax jQuery 工具讓你能夠指定 HTTP 動詞和標頭。這樣一來,你就能夠輕易地作好調用 Web API 後端上的任意類型操作的調用設備。

由於 Web API 模塊是一個普通的 HTTP 前端,因此從一些 .NET 服務器端代碼內部調用它就與從任何其他類型的遠程端點調用沒什麼區別。

(P354) 

作爲使用 WebClient 進行遠程調用的替代選項,可以使用最新的 HttpClient ,它是老式可靠的 WebClient 客戶端的修改及更豐富的版本。 HttpClient 是在 System.Net.Http 名稱空間中定義的。

【第11章】 

(P369) 

一個完整的 Ajax 應用程序是將頁面交互減少到最低限度的 Web 應用程序。

作爲 ASP.NET MVC 開發人員,你要準備好編寫越來越多的 JavaScript 代碼。

(P371) 

一個設置爲 undefined 的變量不會被任何代碼觸及到;而包含 null 的變量會通過你代碼中的一些路徑被分配到某個值。

如果在未賦值的變量上運行 typeof ,就會得到 undefined —— 它本身就是一種獨特的類型。如果在被賦予 null 值的變量上運行 typeof ,你會獲得 object 。

在定義變量時,你應一直使用 var 關鍵字作爲對解析器和你自己的提示。

var 關鍵字並非絕對必要,但強烈建議使用。

如果通過使用 var 對變量進行了聲明,那麼在函數內定義的變量就會僅限於這個函數。如果沒有聲明,變量會被視爲全局的,但它們會保持 undefined ,直到函數執行一次。

在全局範圍中聲明的變量都是全局變量,無論是否使用 var 。

(P372) 

JavaScript 運行時環境會將全局變量存儲爲通過 this 關鍵字引用的隱藏對象的屬性。

缺失 var 的話,你最終獲得的就是全局變量;在賦值中鍵入錯誤的變量名稱,也會得到一個新的全局變量。

(P380) 

嵌套 jQuery 函數被映射成瀏覽器窗口對象的擴展並且用流行的 $ 函數作爲別名。該函數具有以下原型 : function(selector, context) ,選擇器表示在 DOM 上運行的查詢表達式;上下文表示從 DOM 的哪個部分運行該查詢。如果沒有指定上下文,則 jQuery 函數會在整個頁面 DOM 中查找 DOM 元素。

jQuery 函數通常返回一個包裝集 —— 也就是 DOM 元素的集合。非常棒的是,這個包裝集仍然是 jQuery 對象,可使用相同的語法來查詢,併產生一系列查詢。

jQuery 庫的主要目的是運行鍼對 DOM 的 (明智) 查詢並執行鍼對返回項的操作。

一個查詢結果就是一個包裝集。包裝集是包含 DOM 元素集合的對象。元素會按照其在原始文檔中出現的順序被添加到集合中。

(P381) 

包裝集並不是一個特殊的數據容器。“包裝集” 是一個表明查詢結果的特定 jQuery 術語。

爲了循環遍歷包裝集中的元素,你要使用 each 函數。此函數會將一個函數用作參數並基於每個元素調用它。

可以使用 length 屬性來讀取包裝集的大小。也可以使用 size 函數,但 length 屬性會稍微快一點。

請注意, get 函數 (以及索引) 會中斷 jQuery 的連貫性,因爲它會返回 DOM 對象或 DOM 對象的數組。你不能進一步將 jQuery 函數應用於 get 調用的結果。

(P382) 

在 jQuery 中,你有三種基本類型的選擇器 : 基於 ID 的選擇器、層疊樣式表 (CSS) 和標籤名稱。

ID 選擇器會通過 ID 來選取 DOM 元素, ID 選擇器通常只會選擇一個元素。

可以串聯兩個或更多個選擇器來組成更特定的選擇器。

通過多個運算符就能實現串聯。

(P386) 

包裝集上的操作 : 

1. DOM 操作 —— 創建 DOM 樹、添加 / 移除 元素,或修改現有元素;

2. 綁定事件 —— 將處理程序綁定和解除綁定到由 DOM 元素髮起的事件;

3. 樣式化 —— 爲所選元素應用、移除或切換 CSS 類並得到或設置單個 CSS 屬性;

4. 可見性 —— 使用過渡效果及持續時間顯示和隱藏 DOM 元素;

(P387) 

bind 和 unbind 這對函數用於將回調函數附加到指定事件。

unbind 函數並不會移除那些通過 onXXX 這樣的特性直接在標記中插入的處理程序。

jQuery 庫還定義了不少直接函數來綁定指定事件。

事件處理程序會接收一個 jQuery 內部對象 —— Event 對象。該對象會提供一個用於事件的統一編程接口,該接口與萬維網聯盟 (W3C) 的倡議密切相關,並且它解決了某些瀏覽器造成的輕微不同實現所引起的差異性問題。

(P388) 

Event 對象的屬性特徵包括鼠標座標、事件的 JavaScript 時間、使用的是哪個鼠標按鈕,以及事件的目標元素等。

如果選擇動態綁定而非普通綁定,就確保了任何動態添加的能匹配選擇器的元素都會自動附加相同的處理程序。

從 jQuery 1.7 開始,你就該通過 on 和 off 函數來操作動態綁定了。

如果使用的 jQuery 版本比 1.7 低,就要使用 live 和 die 方法作爲 on 和 off 的替代。其語法稍有不同,因爲 live 方法不會將選擇器用作參數,相反它會直接應用於選擇器。

DOM 中的 document 根對象公開了一個只讀的 readyState 屬性,這就是爲了讓你獲知 DOM 的當前狀態並獲悉何時你的頁面準備就緒,能夠開始執行腳本。使用 readyState 屬性是一種絕對可行的方式,只是它有一點麻煩。

(P389) 

可以在頁面或視圖中擁有多個 ready 調用。指定多個 ready 調用時, jQuery 會將指定函數推送到內部堆棧並在 DOM 實際準備好之後按順序對其進行處理。

ready 事件僅會在文檔級別觸發;你不能爲單個元素或包裝集中的任何元素集合定義該事件。

onload 事件是在 HTML 和所有輔助資源都加載之後調用的。 ready 事件是在 DOM 初始化之後調用的。這兩個事件的運行順序可以隨意安排。 onload 事件不能確保頁面 DOM 已加載; ready 事件不能確保所有資源已經加載。

(P390) 

無侵入性 JavaScript 建立了一個基礎原則 —— 任何網頁中的任何行爲都必須是可注入的依賴項並且不是一個構建塊。

限制 UI 依賴項影響的一個方法是使用模板和 KnockoutJS 這樣的特設庫來呈現頁面。
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章