七天来学习ASP.NET MVC (两)——ASP.NET MVC 数据传输
通過第一天的學(xué)習(xí)之后,我們相信您已經(jīng)對(duì)MVC有一些基本了解。
本節(jié)所講的內(nèi)容是在上節(jié)的基礎(chǔ)之上。因此須要確保您是否掌握了上一節(jié)的內(nèi)容。
本章的目標(biāo)是在今天學(xué)習(xí)結(jié)束時(shí)利用最佳實(shí)踐解決方式創(chuàng)建一個(gè)小型的MVC項(xiàng)目。本節(jié)的主要目標(biāo)是了解MVC之間的數(shù)據(jù)傳遞問題。我們會(huì)逐步深入解說。并加入新功能,使項(xiàng)目越來越完好。
系列文章
七天學(xué)會(huì)ASP.NET MVC (一)——深入理解ASP.NET MVC
七天學(xué)會(huì)ASP.NET MVC (二)——ASP.NET MVC 數(shù)據(jù)傳遞
七天學(xué)會(huì)ASP.NET MVC (三)——ASP.Net MVC 數(shù)據(jù)處理
七天學(xué)會(huì)ASP.NET MVC (四)——用戶授權(quán)認(rèn)證問題
七天學(xué)會(huì)ASP.NET MVC (五)——Layout頁面使用和用戶角色管理
?
Controller與 View之間的值傳遞
在上一節(jié)的實(shí)驗(yàn)二中已經(jīng)創(chuàng)建了靜態(tài)View。
然而在實(shí)際使用情況下,View經(jīng)常使用于顯示動(dòng)態(tài)數(shù)據(jù)。
在實(shí)驗(yàn)三中們將在View中動(dòng)態(tài)顯示數(shù)據(jù)。
View將從從Controller獲得Model中的數(shù)據(jù)。
Model是MVC中 表示業(yè)務(wù)數(shù)據(jù)的層。
實(shí)驗(yàn)3 ——使用View數(shù)據(jù)
ViewData相當(dāng)于數(shù)據(jù)字典,包括Controlle和View之間傳遞的全部數(shù)據(jù)。Controller會(huì)在該字典中加入新數(shù)據(jù)項(xiàng),View從字典中讀取數(shù)據(jù)。
1.?創(chuàng)建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 方法中創(chuàng)建Employee 對(duì)象:
1: Employee emp = new Employee(); 2: emp.FirstName = "Sukesh"; 3: emp.LastName="Marla"; 4: emp.Salary = 20000;注意:請(qǐng)確保使用Using語句包括此類,或者使用類的全稱。
1: using WebApplication1.Models;3.?創(chuàng)建ViewData?并返回View
在ViewData中存儲(chǔ)Employee 對(duì)象。
1: ViewData["Employee"] = emp; 2: return View("MyView");4.?在View中顯示Employee?數(shù)據(jù)
打開MyView.cshtml。
從ViewData中獲取Employee 數(shù)據(jù)并依照例如以下代碼顯示:
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.?測(cè)試輸出
按F5執(zhí)行
關(guān)于實(shí)驗(yàn) 3
1. 寫Razor代碼帶花括號(hào)和沒有花括號(hào)有什么差別?
在實(shí)驗(yàn)三中@emp.FirstName能夠使用下面腳本來取代
1: @{ 2: Response.Write(emp.FirstName); 3: }@符號(hào)后沒有花括號(hào)僅僅是簡(jiǎn)單的顯示變量或表達(dá)式的值
2. 為什么須要強(qiáng)制轉(zhuǎn)換類型
ViewData可操作內(nèi)部對(duì)象。每次加入新值。會(huì)封裝成對(duì)象類型,因此每次都須要解壓來提取值。
3. @emp.FirstName @emp.LastName有什么特殊含義?
意味著LastName顯示在FirstName之后并自己主動(dòng)加入空格。
4. 為什么 Employee中的 硬編碼是由Controller創(chuàng)建的 ?
在本文中僅僅是為了實(shí)現(xiàn)實(shí)驗(yàn)?zāi)康?#xff0c;因此採(cǎi)用硬編碼。實(shí)際使用中。是從數(shù)據(jù)庫(kù)或Web服務(wù)中獲取的。
5. 數(shù)據(jù)庫(kù)邏輯,數(shù)據(jù)訪問層。業(yè)務(wù)層分別指的是什么?
- 數(shù)據(jù)訪問層是ASP.NET MVC中是一直隱式存在的,MVC定義中不包括數(shù)據(jù)訪問層的定義。
- 業(yè)務(wù)層是解釋器的先驅(qū),是Model的一部分。
完整的MVC結(jié)構(gòu)
實(shí)驗(yàn)4——ViewBag的使用
ViewBag能夠稱為ViewData的一塊關(guān)于語法的輔助的糖果,ViewBag使用C# 4.0的動(dòng)態(tài)特征。使得ViewData也具有動(dòng)態(tài)特性。
ViewData與ViewBag對(duì)照:
ViewData | ViewBag |
它是Key/Value字典集合 | 它是dynamic類型對(duì)像 |
從Asp.net MVC 1 就有了 | ASP.NET MVC3 才有 |
基于Asp.net 3.5 framework | 基于Asp.net 4.0與.net framework |
ViewData比ViewBag快 | ViewBag比ViewData慢 |
在ViewPage中查詢數(shù)據(jù)時(shí)須要轉(zhuǎn)換合適的類型 | 在ViewPage中查詢數(shù)據(jù)時(shí)不須要類型轉(zhuǎn)換 |
有一些類型轉(zhuǎn)換代碼 | 可讀性更好 |
ViewBag內(nèi)部調(diào)用ViewData。
1. 創(chuàng)建View Bag
在實(shí)驗(yàn)三的基礎(chǔ)之上,使用下面腳本取代第三步中的代碼。
1: ViewBag.Employee = emp;2. 在View中顯示EmployeeData
使用下面代碼來替代實(shí)驗(yàn)三中第四步中的代碼:
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. 測(cè)試輸出
執(zhí)行結(jié)果:
關(guān)于實(shí)驗(yàn)4
能夠傳遞ViewData。接收時(shí)獲取ViewBag嗎?
答案是肯定的。反之亦然。如之前所說的,ViewBag僅僅是ViewData的一塊糖/
ViewData與ViewBag的問題
ViewData和ViewBag 是Contoller與View之間值傳遞的內(nèi)容。可是在實(shí)際使用的過程中,它們并非最佳選擇,接下來我們來看看使用它們的缺點(diǎn):
?
- 性能問題;ViewData中的值都是對(duì)象類型。使用之前必須強(qiáng)制轉(zhuǎn)換為合適的類型。會(huì)加入額外的性能負(fù)擔(dān)。
- 沒有類型安全就沒有編譯時(shí)錯(cuò)誤,假設(shè)嘗試將其轉(zhuǎn)換為錯(cuò)誤的類型,執(zhí)行時(shí)會(huì)報(bào)錯(cuò)。
良好的編程經(jīng)驗(yàn)告訴我們,錯(cuò)誤必須在編譯時(shí)捕獲。
- 數(shù)據(jù)發(fā)送和數(shù)據(jù)接收之間沒有正確的連接;MVC中,Controller和View是松散的連接的。Controller是無法捕獲View變化,View也無法捕獲到Controller內(nèi)部發(fā)生的變化。從Controller傳遞一個(gè)ViewData或ViewBag的值,當(dāng)開發(fā)者正在View中寫入,就必須記錄從Controller中即將獲得什么值。
假設(shè)Controller與View開發(fā)者不是同樣的開發(fā)者,開發(fā)工作會(huì)變得很困難。會(huì)導(dǎo)致很多執(zhí)行時(shí)問題,減少了開發(fā)效率。
實(shí)驗(yàn)5——理解強(qiáng)類型View
ViewData和ViewBag引起的全部問題根源都在于數(shù)據(jù)類型。參數(shù)值的數(shù)據(jù)類型是被封裝在ViewData中的,稱為對(duì)象。
假設(shè)能夠設(shè)置Controller和View之間參數(shù)傳遞的數(shù)據(jù)類型,那么上述問題就會(huì)得到解決,因此從得出強(qiáng)類型View。
接下來,我們看一個(gè)簡(jiǎn)單的樣例,假設(shè)工資大于15000則顯示黃色。低于顯示綠色。
1. 創(chuàng)建View的強(qiáng)類型
在View的頂部加入下面代碼:
@model WebApplication1.Models.Employee
2. 顯示數(shù)據(jù)
在View內(nèi)部輸入@Model.就會(huì)查看到Model類的屬性
加入下面代碼來顯示數(shù)據(jù):
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數(shù)據(jù)。
改動(dòng)action代碼
1: Employee emp = new Employee(); 2: emp.FirstName = "Sukesh"; 3: emp.LastName="Marla"; 4: emp.Salary = 20000; 5: return View("MyView",emp);4. 測(cè)試輸出
關(guān)于實(shí)驗(yàn)5
View中使用類時(shí)須要聲明類的全稱嗎 (Namespace.ClassName)?
加入下面語句,就不須要加入全稱。
1: @using WebApplication1.Models 2: @model Employee是否必須設(shè)置View的強(qiáng)類型View5或是不使用ViewData和ViewBag?
設(shè)置強(qiáng)類型的View是最佳解決方式。
能否將View設(shè)置為多個(gè)Model使用的強(qiáng)類型?
不能夠,實(shí)際項(xiàng)目中在一個(gè)View中想要顯示多個(gè)Model時(shí)以點(diǎn)結(jié)束的。該問題的解決方法將在下一節(jié)討論。
理解ASP.NET MVC 中的View Model
實(shí)驗(yàn)5中已經(jīng)違反了MVC的基本準(zhǔn)則。
依據(jù)MVC,V是View純UI,不包括不論什么邏輯層。
而我們?cè)趯?shí)驗(yàn)5中下面三點(diǎn)違反了MVC的體系架構(gòu)規(guī)則。
1. 附加姓和名顯示全名——邏輯層
2. 使用貨幣顯示工資——邏輯層
3. 使用不同的顏色表示工資值,使用簡(jiǎn)單的邏輯改變了HTML元素的外觀。——邏輯層
ViewModel 解決方法
ViewModel是ASP.NET MVC應(yīng)用中隱式聲明的層。它是用于維護(hù)Model與View之間數(shù)據(jù)傳遞的,是View的數(shù)據(jù)容器。
Model 和 ViewModel 的差別
Model是業(yè)務(wù)相關(guān)數(shù)據(jù),是依據(jù)業(yè)務(wù)和數(shù)據(jù)結(jié)構(gòu)創(chuàng)建的。ViewModel是視圖相關(guān)的數(shù)據(jù)。是依據(jù)View創(chuàng)建的。
詳細(xì)的工作原理
View 與 ViewModel 之間是怎樣關(guān)聯(lián)的?
View將變成ViewModel的強(qiáng)類型View。
Model和 ViewModel 是怎樣關(guān)聯(lián)的?
Model和ViewModel 是互相獨(dú)立的。Controller將依據(jù)Model對(duì)象創(chuàng)建并初始化ViewModel對(duì)象。
接下來我們來看實(shí)驗(yàn)6:
實(shí)驗(yàn)6—— 實(shí)現(xiàn)ViewModel
1. 新建目錄
在項(xiàng)目中創(chuàng)建新目錄并命名為ViewModels。
2. 新建EmployeeViewModel
為了達(dá)到實(shí)驗(yàn)?zāi)康?#xff0c;首先列出我們的實(shí)驗(yàn)需求:
1. 名和姓應(yīng)該合并顯示。
2. 使用貨幣顯示數(shù)量
3. 薪資以不同的顏色來顯示
4. 當(dāng)前登錄用戶也須要在View中顯示。
在ViewModels類中,創(chuàng)建新類并命名為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: }注意。姓和名應(yīng)該使用EmployeeName這一個(gè)屬性。而Salary屬性的數(shù)據(jù)類型是字符串。且有兩個(gè)新的屬性加入稱為SalaryColor和UserName。
3. View中使用ViewModel實(shí)驗(yàn)五中已經(jīng)創(chuàng)建了View的強(qiáng)類型Employee。將它改為 EmployeeViewModel
1: @using WebApplication1.ViewModels 2: @model EmployeeViewModel4. 在View中顯示數(shù)據(jù)
使用下面腳本取代View部分的內(nèi)容
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數(shù)據(jù)而且將強(qiáng)制轉(zhuǎn)換為ViewModel對(duì)象。
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. 測(cè)試輸出
雖然執(zhí)行結(jié)果相似。可是View中不包括不論什么業(yè)務(wù)邏輯。
關(guān)于實(shí)驗(yàn)6
是否意味著。每一個(gè)Model都有一個(gè)ViewModel?
每一個(gè)View有其相應(yīng)的ViewModel。
Model與ViewModel之間存在關(guān)聯(lián)是否是好的實(shí)現(xiàn)方法?
最好的是Model與ViewModel之間相互獨(dú)立。
須要每次都創(chuàng)建ViewModel嗎?假如View不包括不論什么呈現(xiàn)邏輯僅僅顯示Model數(shù)據(jù)的情況下還須要?jiǎng)?chuàng)建ViewModel嗎?
建議是每次都創(chuàng)建ViewModel。每一個(gè)View都應(yīng)該有相應(yīng)的ViewModel,雖然ViewModel包括與Model中同樣的屬性。
假定一個(gè)View不包括不論什么呈現(xiàn)邏輯,僅僅顯示Model數(shù)據(jù)。我們不創(chuàng)建ViewModel會(huì)發(fā)生什么?
無法滿足未來的需求,假設(shè)未來須要加入新數(shù)據(jù)。我們須要從頭開始創(chuàng)建全新的UI。所以假設(shè)我們保持規(guī)定,從開始創(chuàng)建ViewModel。就不會(huì)發(fā)生這樣的情況。
在本實(shí)例中,初始階段的ViewModel將與Model差點(diǎn)兒全然同樣。
實(shí)驗(yàn)7——帶有集合的View
在本實(shí)驗(yàn)中,在View中顯示Employee列表。
1. 改動(dòng)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. 創(chuàng)建結(jié)合ViewModel
在ViewModels 文件下,創(chuàng)建新類并命名為EmployeeListViewModel
1: public class EmployeeListViewModel 2: { 3: public List<employeeviewmodel> Employees { get; set; } 4: public string UserName { get; set; } 5: }?3. 改動(dòng)強(qiáng)類型View的類型
1: @using WebApplication1.ViewModels 2: @model EmployeeListViewModel4. 顯示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. 創(chuàng)建Employee的業(yè)務(wù)邏輯
新建類并命名為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.? 執(zhí)行
關(guān)于實(shí)驗(yàn)7
能否夠制定強(qiáng)類型View列表?是的?為什么要新建EmployeeListViewModel單獨(dú)的類而不直接使用強(qiáng)類型View的列表?1.??? 策劃未來會(huì)出現(xiàn)的呈現(xiàn)邏輯2.??? UserName屬性。UserName是與employees無關(guān)的屬性,與完整View相關(guān)的屬性。為什么刪除EmployeeViewModel 的UserName屬性,而不是將它作為EmployeeListViewModel的一部分?UserName 是同樣的。不須要EmployeeViewModel中加入U(xiǎn)serName。
結(jié)論
以上就是我們第二天所講的內(nèi)容,在第三天我們會(huì)學(xué)習(xí)新內(nèi)容
原文鏈接:http://www.codeproject.com/Articles/897559/Learn-MVC-in-days-Day版權(quán)聲明:本文博主原創(chuàng)文章。博客,未經(jīng)同意不得轉(zhuǎn)載。
轉(zhuǎn)載于:https://www.cnblogs.com/bhlsheji/p/4906546.html
總結(jié)
以上是生活随笔為你收集整理的七天来学习ASP.NET MVC (两)——ASP.NET MVC 数据传输的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux 下安装nodejs,Cent
- 下一篇: 肝脏最怕什么