七天學會ASP.NET MVC (二)——ASP.NET MVC 數據傳遞

經過第一天的學習以後,咱們相信您已經對MVC有一些基本瞭解。html

本節所講的內容是在上節的基礎之上,所以須要確保您是否掌握了上一節的內容。本章的目標是在今天學習結束時利用最佳實踐解決方案建立一個小型的MVC項目,本節的主要目標是瞭解MVC之間的數據傳遞問題。咱們會逐步深刻講解,並添加新功能,使項目愈來愈完善。數據庫

day-two

系列文章編程

七天學會ASP.NET MVC (一)——深刻理解ASP.NET MVC

 

Controller與 View之間的值傳遞

在上一節的實驗二中已經建立了靜態View。然而在實際使用狀況下,View經常使用於顯示動態數據。在實驗三中們將在View中動態顯示數據。安全

View將從從Controller得到Model中的數據。數據結構

Model是MVC中 表示業務數據的層。架構

實驗3 ——使用View數據

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運行

clip_image001

關於實驗 3

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. 數據庫邏輯,數據訪問層,業務層分別指的是什麼?

  • 數據訪問層是ASP.NET MVC中是一直隱式存在的,MVC定義中不包含數據訪問層的定義。
  • 業務層是解釋器的先驅,是Model的一部分。

完整的MVC結構

clip_image003

實驗4——ViewBag的使用

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. 測試輸出

運行結果:

clip_image001[1]

關於實驗4

能夠傳遞ViewData,接收時獲取ViewBag嗎?

答案是確定的,反之亦然。如以前所說的,ViewBag只是ViewData的一塊糖/

ViewData與ViewBag的問題

ViewData和ViewBag 是Contoller與View之間值傳遞的內容。可是在實際使用的過程當中,它們並非最佳選擇,接下來咱們來看看使用它們的缺點:

 

  • 性能問題;ViewData中的值都是對象類型,使用以前必須強制轉換爲合適的類型。會添加額外的性能負擔。
  • 沒有類型安全就沒有編譯時錯誤,若是嘗試將其轉換爲錯誤的類型,運行時會報錯。良好的編程經驗告訴咱們,錯誤必須在編譯時捕獲。
  • 數據發送和數據接收之間沒有正確的鏈接;MVC中,Controller和View是鬆散的鏈接的。Controller是沒法捕獲View變化,View也沒法捕獲到Controller內部發生的變化。從Controller傳遞一個ViewData或ViewBag的值,當開發人員正在View中寫入,就必須記錄從Controller中即將得到什麼值。若是Controller與View開發人員不是相同的開發人員,開發工做會變得很是困難。會致使許多運行時問題,下降了開發效率。

實驗5——理解強類型View

ViewData和ViewBag引發的全部問題根源都在於數據類型。參數值的數據類型是被封裝在ViewData中的,稱爲對象。

若是可以設置Controller和View之間參數傳遞的數據類型,那麼上述問題就會獲得解決,所以從得出強類型View。

接下來,咱們看一個簡單的例子,若是工資大於15000則顯示黃色,低於顯示綠色。

1. 建立View的強類型

在View的頂部添加如下代碼:

@model WebApplication1.Models.Employee

2. 顯示數據

在View內部輸入@Model.就會查看到Model類的屬性

clip_image004

添加如下代碼來顯示數據:

 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. 測試輸出

clip_image005

關於實驗5

View中使用類時須要聲明類的全稱嗎 (Namespace.ClassName)?

添加如下語句,就不須要添加全稱。

 1: @using WebApplication1.Models
 2: @model Employee
 

是否必須設置View的強類型View5或是不使用ViewData和ViewBag?

設置強類型的View是最佳解決方案。

是否能將View設置爲多個Model使用的強類型?

不能夠,實際項目中在一個View中想要顯示多個Model時以點結束的。該問題的解決方法將在下一節討論。

理解ASP.NET MVC 中的View Model

實驗5中已經違反了MVC的基本準則。根據MVC,V是View純UI,不包含任何邏輯層。而咱們在實驗5中如下三點違反了MVC的體系架構規則。

1. 附加姓和名顯示全名——邏輯層

2. 使用貨幣顯示工資——邏輯層

3. 使用不一樣的顏色表示工資值,使用簡單的邏輯改變了HTML元素的外觀。——邏輯層

ViewModel 解決方法

ViewModel是ASP.NET MVC應用中隱式聲明的層。它是用於維護Model與View之間數據傳遞的,是View的數據容器。

Model 和 ViewModel 的區別

Model是業務相關數據,是根據業務和數據結構建立的。ViewModel是視圖相關的數據。是根據View建立的。

具體的工做原理

  1. Controller 處理用戶交互邏輯或簡單的判斷。處理用戶需求
  2. Controller 獲取一個或多個Model數據
  3. Controller 決策哪一個View最符合用戶的請求
  4. Controller 將根據Model數據和View需求建立而且初始化ViewModel對象。
  5. Controller 將ViewModel數據以ViewData或ViewBag或強類型View等對象傳遞到View中。
  6. Controller 返回View。

View 與 ViewModel 之間是如何關聯的?

View將變成ViewModel的強類型View。

Model和 ViewModel 是如何關聯的?

Model和ViewModel 是互相獨立的,Controller將根據Model對象建立並初始化ViewModel對象。

接下來咱們來看實驗6:

實驗6—— 實現ViewModel

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. 測試輸出

clip_image006

儘管運行結果相似,可是View中不包含任何業務邏輯。

關於實驗6

是否意味着,每一個Model都有一個ViewModel?

每一個View有其對應的ViewModel。

Model與ViewModel之間存在關聯是不是好的實現方法?

最好的是Model與ViewModel之間相互獨立。

須要每次都建立ViewModel嗎?假如View不包含任何呈現邏輯只顯示Model數據的狀況下還須要建立ViewModel嗎?

建議是每次都建立ViewModel,每一個View都應該有對應的ViewModel,儘管ViewModel包含與Model中相同的屬性。

假定一個View不包含任何呈現邏輯,只顯示Model數據,咱們不建立ViewModel會發生什麼?

沒法知足將來的需求,若是將來須要添加新數據,咱們須要從頭開始建立全新的UI,因此若是咱們保持規定,從開始建立ViewModel,就不會發生這種狀況。在本實例中,初始階段的ViewModel將與Model幾乎徹底相同。

實驗7——帶有集合的View

在本實驗中,在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.  執行

clip_image007

關於實驗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
相關文章
相關標籤/搜索