我相信在開始第 2 天的學習時,你已經順利地完成了第 1 天的課程。
我們回顧一下第 1 天的主要關注點:
為什么選擇 ASP.NET MVC ?
ASP.NET Webforms 和 ASP.NET MVC 的對比
理解 ASP.NET MVC 的 Controller 以及 Views
提醒:如果你還沒有完成第 1 天的學習,最好先確保完成它。我們的目標是在最后一天用最佳實踐和最新技術方法來創建一個小的 MVC 項目。每一天的 Lab 訓練中,我們都會比之前一天增加一些實用性的功能,這樣看起來會比之前的程序更趨于完美。
在 Lab 2 中,View 的創建都是偏于靜態的。然而在真實的場景中,View 展示的通常是一些動態數據。在下一個 Lab 中,我們將展示 View 中如何動態展示數據。
View 將從 Controller 中獲取以 Model 格式展示的數據。
Model
在 ASP.NET MVC 中,Model 展示的是業務數據。
ViewData 是一個字典,它存儲了 Controller 傳輸給 View 的數據。Controller 將向 ViewData 字典添加條目,然后 View 從這個字典里讀取。現在我們開始做一個 Demo 吧。
第一步:創建一個 Model 類
在 Model 文件夾下創建一個新的類,命名為 Employee。
public class Employee{ public string FirstName { get; set; } public string LastName { get; set; } public int Salary { get; set; }}
第二步:從 Controller 中獲取 Model
在 GetView 方法中創建一個 Employee 對象。
Employee emp = new Employee();emp.FirstName = "Sukesh";emp.LastName="Marla";emp.Salary = 20000;
注意:確保在類中使用 Using 語句將 Model 引入,否則就要在編寫程序時使用 Employee 類的全名。
using Webapplication1.Models;
第三步:創建 ViewData 并返回 View
在 ViewData 中存儲 Employee 對象。
ViewData["Employee"] = emp;return View("MyView");
第四步:在 View 中展示 Employee 數據
打開文件 MyView.cshtml。從 ViewData 中檢索 Employee 數據并展示。
<div> @{ WebApplication1.Models.Employee emp = (WebApplication1.Models.Employee)ViewData["Employee"]; } <b>Employee Details </b><br/> Employee Name : @[email protected] <br/> Employee Salary: @emp.Salary.ToString("C")</div>
第五步:測試輸出
按下 F5,測試應用。
寫 Razor 代碼的過程中,使用花括號「『{』和『}』」和不使用花括號,有什么區別?
在 lab 3 中,@emp.FirstName 可以使用以下代碼替換。
@{ Response.Write(emp.FirstName);}
如果在 @ 后沒有使用花括號,那么它僅僅是為了展示變量或者表達式的值。
為什么需要強制轉換?
ViewData 內部承載了一些對象。每一次增加一個新值,就會把它轉換為 Object 類型。
所以每一次都需要強制轉換來獲取對象的值。
「@emp.FirstName @emp.LastName」的含義是什么?
這個意味著 LastName 展示在 FirstName 之后,并通過空格隔開。
如果只想使用一個 @ 關鍵字,能做到剛才的效果嗎?
答案是肯定的。通過語法 @(emp.FirstName+””+emp.LastName)。
為什么在 Controller 類中要硬編碼 Employee 類?
這僅僅是為了展示 demo。實際上,我們將會在數據庫,WCF ,Web Service 或者其它地方獲取數據。
什么是數據庫邏輯,數據訪問層以及業務層?
數據訪問層在 ASP.NET MVC 中是一個未顯示的層。實際上,它一直存在,但是在 MVC 的定義中從來沒包含過它。
業務層像之前所解釋的,它是 Model 的一部分。
完整的 MVC 結構。
ViewBag 就像是 ViewData 的語法蜜糖。ViewBag 運用 C# 4.0 的動態特征,使得 ViewData 動態化。
ViewBag 內部運用 ViewData。
第一步:創建 View Bag
繼續 Lab 3,然后用如下代碼片段替換 Lab 3 中的第三步:
ViewBag.Employee = emp;
第二步:在 View 中展示 EmployeeData
用如下的代碼片段替換 Lab3 中的第四步:
@{ WebApplication1.Models.Employee emp = (WebApplication1.Models.Employee)ViewBag.Employee;}Employee DetailsEmployee Name: @emp.FirstName @emp.LastName Employee Salary: @emp.Salary.ToString("C")
第三步:測試并輸出
按下 F5 并測試應用程序。
我們是否可以傳輸 ViewData,然后以 ViewBag 的形式獲取到?
答案是肯定的。反過來也是可以的。就像我之前所提到過的,ViewBag 僅僅是 ViewData 的語法蜜糖。
ViewData 和 ViewBag 是 Controller 與 View 之間傳輸數據的很好選擇方式。但是在實際的項目應用中,它們之中的任何一個都不是最佳的實踐方式。現在我們來討論一下運用 ViewData 和 ViewBag 的缺點吧。
ViewData 中的數據類型是 Object。所以我們在使用之前需要進行正確的類型轉換。這個操作為性能帶來了額外的負擔。
如果我們嘗試將類型轉換為錯誤的類型,或者我們在檢索對象值的時候使用錯誤的 Key 值,我們將會在運行時出錯。但是對于一個好的編程實踐而言,錯誤應該在編譯的時候就被捕獲到。
作為一個開發者,我個人認為這是一個很主要的問題。
在 MVC 中, Controller 和 View 彼此之間的連接是弱連接,松散的。
Controller 完全不會關心 View 之中發生了什么,同理,View 也完全不會關心 Controller 之中發生了什么。
從 Controller 中我們可以傳輸一個或者多個 ViewData 或者 ViewBag 值。現在,當一個開發者要寫一個 View 時,他需要記住 Controller 將要傳輸什么。如果一個 Controller 開發者與 View 開發者不是同一個人,那么情況將會變得更困難。因為是完全的不關心,所以這將導致開發過程的低效率,也有可能引起運行錯誤。
剛才上述關于 ViewData 和 ViewBag 的三點問題可以歸結于是由數據類型所引起的。ViewData 中存儲的數據類型是 「Object」。
如果以某種方式,我們能夠為傳輸在 Controller 和 View 中的數據設置數據類型,那么問題將會迎刃而解,而這種方式便是強類型 Views。
現在讓我們做一個 Demo。這次我們將會提升 View 的需求到下一個級別層次。如果薪水大于 15000,那么那么就展示為黃顏色,否則為綠顏色。
第一步:創建強類型的 View
在 View 的頂部加上如下代碼:
@model WebApplication1.Models.Employee
基于這條語句,使得我們的 View 成為一個類型為 Employee 的強類型視圖。
第二步:展示數據
現在,在 View 中,僅僅使用 @Model 和 Dot(.) 操作就可以智能獲取 Model,即 Empolyee 的所有數據值。
寫下如下代碼來展示數據:
Employee DetailsEmployee Name : @Model.FirstName @Model.LastName @if(Model.Salary>15000){ <span style="background-color:yellow"> Employee Salary: @Model.Salary.ToString("C") </span>}else{ <span style="background-color:green"> Employee Salary: @Model.Salary.ToString("C") </span>}
第三步:從 Controller 的 Action 方法傳輸 Model 數據
更改 Action 方法為如下代碼片段:
Employee emp = new Employee();emp.FirstName = "Sukesh";emp.LastName="Marla";emp.Salary = 20000; return View("MyView",emp);
第四步:測試并輸出
每次在 View 中的類型聲明都需要使用類的全稱嗎,即 Namespace.ClassName ?
答案是否定的。我們可以運用 「using」聲明。
@using WebApplication1.Models@model Employee
我們必須總是使用強類型視圖嗎,還是我們可以偶爾使用一下 ViewData 或者 ViewBag ?
如果想實踐最佳方式,最好使用強類型視圖。
我們可以為強類型視圖的 View 使用多個 Model 類型嗎 ?
答案是否定的。在實際項目中,當我們想要在一個視圖中展示多個 Model 時,我們經常會結束在這點上。這一需求的解決方案將在下一節中討論。
在 Lab 5 中我們已經違反了 MVC 的準則。根據 MVC, V 代表的是純粹的 UI。它應該不包含任何的邏輯。我們已經通過如下的三點違反了 MVC 的結構規則:
附加了 First Name 和 Last Name,并且用它們展示了全名。這屬于邏輯操作。
以貨幣形式展示了 Salary。這屬于邏輯操作。
展示了不同工資的不同顏色。這些基于不同值的簡單的操作改變了 HTML 元素的外觀。這屬于邏輯操作。
除了以上三點,這里還有一個更值得討論的問題點。
這一種情形是,我們想要在 View 中展示不同類型的數據。比如:顯示當前登錄的用戶名稱和雇員數據。
我們可以使用如下兩種方式實現這個問題:
向 Employee 類增加一個 UserName 屬性。每一次我們想要在視圖中展示一個新數據,我們就像 Employee 類中增加一個屬性。這似乎是不合理的,這個屬性也許和 Employee 沒有關聯。這也違反了 SOLID 的 SRP 準則。
運用 ViewBag 或者 ViewData。這個方法我們已經在剛才討論了其弊端。
ViewModel 是 ASP.NET MVC 應用中沒有聲明出的層。它適合于 Model 和 View 之間并且為 View 作為一個數據容器。
Model 和 ViewModel 的區別是什么?
Model 特指業務數據。它基于業務和數據結構創建。ViewModel 特指 View 數據。它基于視圖 View 創建。
ViewModel是如何工作的?
工作原理非常簡單。
Controller 處理用戶的交互邏輯,或者簡單來說,處理用戶請求。
Controller 獲得一個或多個 Model 數據。
Controller 將決定哪個 View 為請求作出正確回應。
Controller 將會根據視圖的需求從接收的 Model 數據中創建并初始化 ViewModel 對象。
Controller 將會以 ViewData/ViewBag/強類型 View 的方式傳輸 ViewModel 數據給 View。
Controller 將會返回 View。
View 和 ViewModel 將如何關聯?
View 將會是一個以 ViewModel 為強類型的視圖。
Model 和 ViewModel 將如何關聯?
Model 和 ViewModel 彼此之間應該是獨立的。Controller 將會基于一個或多個 Model 對象來創建并初始化 ViewModel 對象。
讓我們做一個小的 Lab 來更好地理解它吧。
第一步:創建一個文件夾
在項目中命名一個文件夾,命名為 ViewModels。
第二步:創建 EmployeeViewModel
為了做這一步,我們先來理清一下 View 的所有需求。
First Name 和 LastName 需要合并展示,所以在展示前它們應該是合并的。
使用貨幣形式來顯示 Amount。
不同的 Salary 展示出不同的顏色。
當前的 User Name 也要展示在視圖中。
在 ViewModels 文件夾下創建一個 EmployeeViewModel 類,如下所示:
public class EmployeeViewModel{
新聞熱點
疑難解答