經過第一天的學習以後,咱們相信您已經對MVC有一些基本瞭解。html
本節所講的內容是在上節的基礎之上,所以須要確保您是否掌握了上一節的內容。本章的目標是在今天學習結束時利用最佳實踐解決方案建立一個小型的MVC項目,本節的主要目標是瞭解MVC之間的數據傳遞問題。咱們會逐步深刻講解,並添加新功能,使項目愈來愈完善。數據庫
系列文章編程
在上一節的實驗二中已經建立了靜態View。然而在實際使用狀況下,View經常使用於顯示動態數據。在實驗三中們將在View中動態顯示數據。安全
View將從從Controller得到Model中的數據。數據結構
Model是MVC中 表示業務數據的層。架構
ViewData至關於數據字典,包含Controlle和View之間傳遞的全部數據。Controller會在該字典中添加新數據項,View從字典中讀取數據。mvc
1. 建立Model 類工具
在Model文件夾下新建Employee類,以下。性能
1: public class Employee
2:
3: {
4: public string FirstName { get; set; }
5:
6: public string LastName { get; set; }
7:
8: public int Salary { get; set; }
9:
10: }
2. 在Controller 中獲取Model學習
在GetView 方法中建立Employee 對象:
1: Employee emp = new Employee();
2: emp.FirstName = "Sukesh";
3: emp.LastName="Marla";
4: emp.Salary = 20000;
注意:請確保使用Using語句包含此類,或者使用類的全稱。
1: using WebApplication1.Models;
3. 建立ViewData 並返回View
在ViewData中存儲Employee 對象。
1: ViewData["Employee"] = emp;
2: return View("MyView");
4. 在View中顯示Employee 數據
打開MyView.cshtml。
從ViewData中獲取Employee 數據並按照以下代碼顯示:
1: <div>
2: @{
3: WebApplication1.Models.Employee emp=(WebApplication1.Models.Employee)
4: ViewData["Employee"];
5: }
6:
7: <b>Employee Details </b><br />
8: Employee Name : @emp.FirstName@emp.LastName <br />
9: Employee Salary: @emp.Salary.ToString("C")
10: </div>
5. 測試輸出
按F5運行
1. 寫Razor代碼帶花括號和沒有花括號有什麼區別?
在實驗三中@emp.FirstName可以使用如下腳原本代替
1: @{
2: Response.Write(emp.FirstName);
3: }
@符號後沒有花括號只是簡單的顯示變量或表達式的值
2. 爲何須要強制轉換類型
ViewData可操做內部對象,每次添加新值,會封裝成對象類型,所以每次都須要解壓來提取值。
3. @emp.FirstName @emp.LastName有什麼特殊含義?
意味着LastName顯示在FirstName以後並自動添加空格。
4. 爲何 Employee中的 硬編碼是由Controller建立的 ?
在本文中只是爲了實現實驗目的,所以採用硬編碼,實際使用中,是從數據庫或Web服務中獲取的。
5. 數據庫邏輯,數據訪問層,業務層分別指的是什麼?
完整的MVC結構
ViewBag能夠稱爲ViewData的一塊關於語法的輔助的糖果,ViewBag使用C# 4.0的動態特徵,使得ViewData也具備動態特性。
ViewData與ViewBag對比:
ViewData |
ViewBag |
它是Key/Value字典集合 |
它是dynamic類型對像 |
從Asp.net MVC 1 就有了 |
ASP.NET MVC3 纔有 |
基於Asp.net 3.5 framework |
基於Asp.net 4.0與.net framework |
ViewData比ViewBag快 |
ViewBag比ViewData慢 |
在ViewPage中查詢數據時須要轉換合適的類型 |
在ViewPage中查詢數據時不須要類型轉換 |
有一些類型轉換代碼 |
可讀性更好 |
ViewBag內部調用ViewData。
1. 建立View Bag
在實驗三的基礎之上,使用如下腳本代替第三步中的代碼。
1: ViewBag.Employee = emp;
2. 在View中顯示EmployeeData
使用如下代碼來替代實驗三中第四步中的代碼:
1: @{
2: WebApplication1.Models.Employee emp = (WebApplication1.Models.Employee)
3: ViewBag.Employee;
4: }
5: Employee Details
6:
7: Employee Name: @emp.FirstName @emp.LastName
8:
9: Employee Salary: @emp.Salary.ToString("C")
3. 測試輸出
運行結果:
能夠傳遞ViewData,接收時獲取ViewBag嗎?
答案是確定的,反之亦然。如以前所說的,ViewBag只是ViewData的一塊糖/
ViewData與ViewBag的問題
ViewData和ViewBag 是Contoller與View之間值傳遞的內容。可是在實際使用的過程當中,它們並非最佳選擇,接下來咱們來看看使用它們的缺點:
ViewData和ViewBag引發的全部問題根源都在於數據類型。參數值的數據類型是被封裝在ViewData中的,稱爲對象。
若是可以設置Controller和View之間參數傳遞的數據類型,那麼上述問題就會獲得解決,所以從得出強類型View。
接下來,咱們看一個簡單的例子,若是工資大於15000則顯示黃色,低於顯示綠色。
1. 建立View的強類型
在View的頂部添加如下代碼:
@model WebApplication1.Models.Employee
2. 顯示數據
在View內部輸入@Model.就會查看到Model類的屬性
添加如下代碼來顯示數據:
1: Employee Details
2:
3: Employee Name : @Model.FirstName @Model.LastName
4:
5: @if(Model.Salary>15000)
6: {
7: <span style="background-color:yellow">
8: Employee Salary: @Model.Salary.ToString("C")
9: </span>
10: }
11: else
12: {
13: <span style="background-color:green">
14:
15: Employee Salary: @Model.Salary.ToString("C")
16: </span>
17: }
3. 從Controller Action方法中傳遞Model數據。
修改action代碼
1: Employee emp = new Employee();
2: emp.FirstName = "Sukesh";
3: emp.LastName="Marla";
4: emp.Salary = 20000;
5: return View("MyView",emp);
4. 測試輸出
View中使用類時須要聲明類的全稱嗎 (Namespace.ClassName)?
添加如下語句,就不須要添加全稱。
1: @using WebApplication1.Models
2: @model Employee
是否必須設置View的強類型View5或是不使用ViewData和ViewBag?
設置強類型的View是最佳解決方案。
是否能將View設置爲多個Model使用的強類型?
不能夠,實際項目中在一個View中想要顯示多個Model時以點結束的。該問題的解決方法將在下一節討論。
實驗5中已經違反了MVC的基本準則。根據MVC,V是View純UI,不包含任何邏輯層。而咱們在實驗5中如下三點違反了MVC的體系架構規則。
1. 附加姓和名顯示全名——邏輯層
2. 使用貨幣顯示工資——邏輯層
3. 使用不一樣的顏色表示工資值,使用簡單的邏輯改變了HTML元素的外觀。——邏輯層
ViewModel是ASP.NET MVC應用中隱式聲明的層。它是用於維護Model與View之間數據傳遞的,是View的數據容器。
Model 和 ViewModel 的區別
Model是業務相關數據,是根據業務和數據結構建立的。ViewModel是視圖相關的數據。是根據View建立的。
具體的工做原理
View 與 ViewModel 之間是如何關聯的?
View將變成ViewModel的強類型View。
Model和 ViewModel 是如何關聯的?
Model和ViewModel 是互相獨立的,Controller將根據Model對象建立並初始化ViewModel對象。
接下來咱們來看實驗6:
1. 新建文件夾
在項目中建立新文件夾並命名爲ViewModels。
2. 新建EmployeeViewModel
爲了達到實驗目的,首先列出咱們的實驗需求:
1. 名和姓應該合併顯示。
2. 使用貨幣顯示數量
3. 薪資以不一樣的顏色來顯示
4. 當前登陸用戶也須要在View中顯示。
在ViewModels類中,建立新類並命名爲EmployeeViewModel,以下所示:
1: public class EmployeeViewModel
2: {
3: public string EmployeeName { get; set; }
4: public string Salary { get; set; }
5: public string SalaryColor { get; set; }
6: public string UserName{get;set;}
7: }
注意,姓和名應該使用EmployeeName這一個屬性。而Salary屬性的數據類型是字符串,且有兩個新的屬性添加稱爲SalaryColor和UserName。
3. View中使用ViewModel
實驗五中已經建立了View的強類型Employee。將它改成 EmployeeViewModel
1: @using WebApplication1.ViewModels
2: @model EmployeeViewModel
4. 在View中顯示數據
使用如下腳本代替View部分的內容
1: Hello @Model.UserName
2: <hr />
3: <div>
4: <b>Employee Details</b><br />
5: Employee Name : @Model.EmployeeName <br />
6: <span style="background-color:@Model.SalaryColor">
7: Employee Salary: @Model.Salary
8: </span>
9: </div>
5. 新建並傳遞ViewModel
在GetView方法中,獲取Model數據而且將強制轉換爲ViewModel對象。
1: public ActionResult GetView()
2: {
3: Employee emp = new Employee();
4: emp.FirstName = "Sukesh";
5: emp.LastName="Marla";
6: emp.Salary = 20000;
7:
8: EmployeeViewModel vmEmp = new EmployeeViewModel();
9: vmEmp.EmployeeName = emp.FirstName + " " + emp.LastName;
10: vmEmp.Salary = emp.Salary.ToString("C");
11: if(emp.Salary>15000)
12: {
13: vmEmp.SalaryColor="yellow";
14: }
15: else
16: {
17: vmEmp.SalaryColor = "green";
18: }
19:
20: vmEmp.UserName = "Admin"
21:
22: return View("MyView", vmEmp);
23: }
6. 測試輸出
儘管運行結果相似,可是View中不包含任何業務邏輯。
是否意味着,每一個Model都有一個ViewModel?
每一個View有其對應的ViewModel。
Model與ViewModel之間存在關聯是不是好的實現方法?
最好的是Model與ViewModel之間相互獨立。
須要每次都建立ViewModel嗎?假如View不包含任何呈現邏輯只顯示Model數據的狀況下還須要建立ViewModel嗎?
建議是每次都建立ViewModel,每一個View都應該有對應的ViewModel,儘管ViewModel包含與Model中相同的屬性。
假定一個View不包含任何呈現邏輯,只顯示Model數據,咱們不建立ViewModel會發生什麼?
沒法知足將來的需求,若是將來須要添加新數據,咱們須要從頭開始建立全新的UI,因此若是咱們保持規定,從開始建立ViewModel,就不會發生這種狀況。在本實例中,初始階段的ViewModel將與Model幾乎徹底相同。
在本實驗中,在View中顯示Employee列表。
1. 修改EmployeeViewModel 類
刪除UserName屬性
1: public class EmployeeViewModel
2: {
3: public string EmployeeName { get; set; }
4: public string Salary { get; set; }
5: public string SalaryColor { get; set; }
6: }
2. 建立結合ViewModel
在ViewModels 文件下,建立新類並命名爲EmployeeListViewModel
1: public class EmployeeListViewModel
2: {
3: public List<employeeviewmodel> Employees { get; set; }
4: public string UserName { get; set; }
5: }
3. 修改強類型View的類型
1: @using WebApplication1.ViewModels
2: @model EmployeeListViewModel
4. 顯示View中全部的Employee
1: <body>
2: Hello @Model.UserName
3: <hr />
4: <div>
5: <table>
6: <tr>
7: <th>Employee Name</th>
8: <th>Salary</th>
9: </tr>
10: @foreach (EmployeeViewModel item in Model.Employees)
11: {
12: <tr>
13: <td>@item.EmployeeName</td>
14: <td style="background-color:@item.SalaryColor">@item.Salary</td>
15: </tr>
16: }
17: </table>
18: </div>
19: </body>
5. 建立Employee的業務邏輯
新建類並命名爲EmployeeBusinessLayer ,並帶有GetEmployees()方法。
1: public class EmployeeBusinessLayer
2: {
3: public List<employee> GetEmployees()
4: {
5: List<employee> employees = new List<employee>();
6: Employee emp = new Employee();
7: emp.FirstName = "johnson";
8: emp.LastName = " fernandes";
9: emp.Salary = 14000;
10: employees.Add(emp);
11:
12: emp = new Employee();
13: emp.FirstName = "michael";
14: emp.LastName = "jackson";
15: emp.Salary = 16000;
16: employees.Add(emp);
17:
18: emp = new Employee();
19: emp.FirstName = "robert";
20: emp.LastName = " pattinson";
21: emp.Salary = 20000;
22: employees.Add(emp);
23:
24: return employees;
25: }
26: }
27: </employee></employee></employee>
6.從控制器中傳參
1: public ActionResult GetView()
2: {
3: EmployeeListViewModel employeeListViewModel = new EmployeeListViewModel();
4:
5: EmployeeBusinessLayer empBal = new EmployeeBusinessLayer();
6: List<employee> employees = empBal.GetEmployees();
7:
8: List<employeeviewmodel> empViewModels = new List<employeeviewmodel>();
9:
10: foreach (Employee emp in employees)
11: {
12: EmployeeViewModel empViewModel = new EmployeeViewModel();
13: empViewModel.EmployeeName = emp.FirstName + " " + emp.LastName;
14: empViewModel.Salary = emp.Salary.ToString("C");
15: if (emp.Salary > 15000)
16: {
17: empViewModel.SalaryColor = "yellow";
18: }
19: else
20: {
21: empViewModel.SalaryColor = "green";
22: }
23: empViewModels.Add(empViewModel);
24: }
25: employeeListViewModel.Employees = empViewModels;
26: employeeListViewModel.UserName = "Admin";
27: return View("MyView", employeeListViewModel);
28: }
29: </employeeviewmodel></employeeviewmodel></employee>
7. 執行
是否能夠制定強類型View列表?
是的 爲何要新建EmployeeListViewModel單獨的類而不直接使用強類型View的列表?1. 策劃將來會出現的呈現邏輯2. UserName屬性。UserName是與employees無關的屬性,與完整View相關的屬性。爲何刪除EmployeeViewModel 的UserName屬性,而不是將它做爲EmployeeListViewModel的一部分?UserName 是相同的,不須要EmployeeViewModel中添加UserName。
以上就是咱們次日所講的內容,在第三天咱們會學習新內容
數據傳遞是MVC知識的重要組成部分,深刻理解了這部分知識,可以幫助咱們更好的進行MVC的開發。同時,請記得藉助開發工具來助力開發過程,使用 ComponentOne Studio ASP.NET MVC 這款輕量級控件,工做效率大大提升的同時,工做量也會大大減小。
原文連接:http://www.codeproject.com/Articles/897559/Learn-MVC-in-days-Day