第1章、入門
本章主要內容:
- ASP.NET MVC 5概述
- 其應用程序的創建方法
- 其應用程序的及結構
概述:將MVC設計模式應用於ASP.NET框架
ASP.NET 1.0支持兩層抽象:
System.Web.UI:Web Forms層,由服務器控件和ViewState等組成。
System.Web:管道程序,提供基本的Web堆棧,包括組件模塊、處理程序和HTTP堆棧。
MVC模式簡介:MVC將UI分為三個主要部分:
- 模型:一組類,描述了要處理的數據及修改和操作數據的業務規則
- 視圖:一組.cshtml,定義UI的顯示方式
- 控制器:一組類,用於處理來自用戶、整個應用程序流以及特定程序邏輯的通信
第2章、控制器
本章主要內容:
- 控制器的角色
- 例程:MVC Music Store
- 控制器基礎
控制器如何響應HTTP請求並將處理的信息返回給瀏覽器?控制器和控制器操作的功能?
控制器主要負責響應用戶的輸入,同時修改模型。——>程序流、輸入數據的處理和對相關視圖提供輸出數據。
URL首先告知路由機制實例化哪個控制器,調用哪個操作方法,並為該方法提供參數。——>然后控制器的方法決定使用哪個視圖,並對該視圖渲染。(MVC是方法調用結果,而非動態生成(腳本生成)頁面。
例程:MVC Music Store下載地址:http://mvcmusicstore.codeplex.com/(涵蓋了構建一個ASP.NET MVC程序的基本知識)。
第4章、模型
4.2為商店管理器構造基架
4.2.1基架的含義:
用模板創建M、V、C代碼,這個代碼生成的過程就成為“基架”,即生成CRUD功能的樣板代碼。通過基架,可以檢測模型類的定義(決定了后面的名字),然后生成控制器以及關聯的視圖,有時還有數據訪問類;基架決定生成代碼有怎樣的功能、這些類如何放置以使程序正常工作。個人認為類似於MFC類向導。
基架選項:NuGet庫全是運用特定設計模式和技術來生成代碼的基架(基架庫)——>所以可以自定義、修改基架,也可以通過NuGet搜索scaffolder,查找基架。
右擊Controllers文件夾,添加控制器(派生自Controller),選擇MVC 5 常用基架模板(擴展基架P67):
- MVC 5 Contorller——Empty(MVC 5 控制器 - 空):這個選項將會在Controllers文件夾下添加一個自定義名稱(彈框中自己輸)的控制器類。此時該類只有Index方法:返回一個Veiw(),即一個默認的ViewResult實例的視圖;在Views文件夾中不會生成任何視圖(因為它用默認視圖)。
- MVC 5 Controller with read/write Actions(包含讀/寫操作的MVC 5 控制器):相對於Empty,增加了Details(int id)、Create()、Edit(int id)、Delete(int id)方法(此時和前面1的Index一樣:GET),還有三個和Index不一樣(在方法前面加上[HttpPost]):Create(FormCollection collection)、Edit(int id, FormCollection collection)、Delete(int id, FormCollection collection)。但是這些操作並沒有任何實際意義,因為沒有自己的代碼和創建關聯的視圖。
- Web API 2 API Controller Scaffolders(泛指):添加一個繼承自ApiController的控制器,可以為程序創建Web API。
- MVC 5 Controller with Views, Using Enity Framework(包含視圖的控制器,並使用EF框架):生成了整套Actions的控制器以及相關視圖,還生成了與數據庫交互的數據上下文類(繼承自DbContext)。基架會檢測所選擇的模型的所有屬性,因為要用它們創建——>控制器、視圖、數據上下文(可以新建,也可以用現有的)。
4.2.2基架和實體框架:
新建的MVC5 項目會自動包含對實體框架(EF)的引用。EF是一個對象關系映像(ORM)框架,它知道如何在關系數據庫中保存.NET對象,而且還可以用LINQ查詢檢索那些已經保存在關系數據庫中的.NET對象。基架沒有要求一定要用EF,也可以用其他的ORM或數據訪問庫。基架更沒有強制要求使用數據庫(不管是不是關系型),因為可以使用任何數據訪問技術或數據源來構建應用程序,如CSV(逗號分隔的文本)或采用使用了全套WS-*協議組件的Web服務。
但是EF支持數據庫優先、模型優先、代碼優先(MVC基架)的開發風格。代碼優先:在不創建數據庫模式、也不打開VS設計器的情況下,可以向SQL Server存儲或檢索信息;或者直接編寫純C#類,因為EF知道如何存儲其實例的正確位置,這種類的屬性可以都是虛擬屬性virtual,雖然這不是必須的,但這樣可以為EF提供一個指向純C#類集的鈎子(hook),並為EF啟用了一些特性(如高效的修改跟蹤機制efficient change tracking mechanism)——>所以EF知道模型屬性值的修改時刻,並在這一時刻生成並執行一個SQL UPDATE語句,使這些改變與數據庫保持一致。
1.關於代碼優先,EF還遵照了很多約定:例如要把模型類Album的對象存儲在數據庫中,EF就認為是要把該數據存儲在數據庫中一個Albums表中;如果要存儲的對象有ID屬性,EF就認為這個屬性就是主鍵值,並把這個值賦給SQL Server中對應表的自增(標識)鍵列;對外鍵關系、數據庫名稱也有約定:這些約定取代了以前需要給ORM的所有映像和配置。如果要用現有的數據庫,那么需要提供映射元數據。
此外,還可以自定義約定:當EF的默認約定建立數據模型的方式和我們想要的不一致:以前的EF版本的解決辦法是使用數據注解或FluentAPI(但是手動配置所有選項太過乏味,就選擇默認約定);現有版本EF可以通過添加自定義約定覆蓋主鍵定義,或者改變默認的表映射(以滿足自己的團隊命名約定),更好的是,可以創建可重用的約定類和特性(根據自己的需要精確配置),並應用到任何模型和屬性上,使得開發像標准的EF一樣輕松。
2.DbContext類:使用EF的代碼優先方法,需要使用EF的DbContext類派生出一個數據上下文類來訪問數據庫,它具有多個DbSet<T>類型的屬性,其中每一個T代表一個要持久保存的對象;可以把DbSet<T>想象成一個泛型列表,它知道如何在父上下文中加載和保存數據。
數據訪問策略的選擇:數據訪問方法已經出現多種,但方法的選擇依賴於應用程序的類型以及開發團隊的選擇。領域驅動設計(DDD)是一種團隊使用的方法,可以用來處理復雜的程序。還有另一種更主要的團隊開發模式——命令查詢職責分離(CQRS)用來開發復雜程序。DDD和CQRS使用的很流行的設計模式包括庫和工作單元設計模式。其中庫設計模式的優勢之一是:可以在數據訪問的代碼和程序其他部分之間創建一個正常邊界——這個邊界可以提高代碼的單元測試能力(但這不是默認的基架生成代碼的優勢,即默認的基架不能提高單元測試能力,因為默認基架的硬編碼是依賴於EF的)。
4.2.3通過基架添加控制器:
對話框Add Scaffolder—>Add Controller:填寫控制器名、模型類、數據上下文類,后兩者都是模型類—>這一步是選擇新建數據上下文才有,點擊New data context,在New Data Context對話框(需要輸入訪問數據庫的類名,包括名稱空間:必要時改變;但是要訪問數據庫,就需要在控制器中實例化數據上下文類)
在控制器中,方法將上下文屬性對應的數據庫的數據加載到列表並作為模型傳遞給默認視圖,加載可以分為:預加載(.Include(a => a.上下文的屬性)和延遲加載策略(默認策略)
?還未理解透徹——》延遲加載策略:EF根據需要來加載,即當需要時,才發送額外的查詢並加載數據。預加載Include方法則可以優化/減少構建完整模型的查詢次數。
代碼:var albums = db.Albums.Include(a => a.Artist).Include(a => a.Genre); //延遲加載:var albums = db.Albums;
return View(albums.ToList());
4.2.4執行基架的代碼:
1.用EF創建數據庫:EF的代碼優先會盡可能使用約定而非配置——>如果不配置從模型到數據庫的表和列的具體映射,EF會使用約定創建一個數據庫模式;如果在運行時不配置一個具體的數據庫連接,EF會使用約定創建一個連接。
顯式配置數據庫連接:①向web.config文件中添加一個連接字符串②還可以按照約定,EF
不配置:EF將嘗試連接SQL Server的LocalDB實例(就是連接SQL Server的本地服務器),並且查找與數據上下文類同名的數據庫。此時,如果連接成功,但找不到數據庫,那么EF就會創建一個數據庫。在基架創建完成后,運行程序並導航到/StoreManager,就會發現EF已經在LocalDB中創建了一個名為MvcMusicStore.Models.MusicStoreDB的數據庫。
2.使用數據庫初始化器:
3.播種數據庫:
4.3編輯專輯
4.3.1創建編輯專輯的資源:
1.模型和視圖模型終極版:
2.Edit視圖:
4.3.2響應編輯時的POST請求:
1.編輯happy path:
2.編輯sad path:
4.4模型綁定
4.4.1DefaultModeBinder:
4.4.2顯式模型綁定: