七天學(xué)會(huì)ASP.NET MVC (一)——深入理解ASP.NET MVC
為平塘等地區(qū)用戶提供了全套網(wǎng)頁(yè)設(shè)計(jì)制作服務(wù),及平塘網(wǎng)站建設(shè)行業(yè)解決方案。主營(yíng)業(yè)務(wù)為成都網(wǎng)站設(shè)計(jì)、成都網(wǎng)站建設(shè)、平塘網(wǎng)站設(shè)計(jì),以傳統(tǒng)方式定制建設(shè)網(wǎng)站,并提供域名空間備案等一條龍服務(wù),秉承以專業(yè)、用心的態(tài)度為用戶提供真誠(chéng)的服務(wù)。我們深信只要達(dá)到每一位用戶的要求,就會(huì)得到認(rèn)可,從而選擇與我們長(zhǎng)期合作。這樣,我們也可以走得更遠(yuǎn)!
七天學(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頁(yè)面使用和用戶角色管理
七天學(xué)會(huì)ASP.NET MVC (六)——線程問題、異常處理、自定義URL
引言
最后一篇學(xué)什么
實(shí)驗(yàn)32—整理項(xiàng)目組織結(jié)構(gòu)
關(guān)于實(shí)驗(yàn)32
實(shí)驗(yàn)33——?jiǎng)?chuàng)建單頁(yè)應(yīng)用——第一部分—安裝
什么是Areas?
關(guān)于實(shí)驗(yàn)33
實(shí)驗(yàn)34——?jiǎng)?chuàng)建單頁(yè)應(yīng)用——第二部分—顯示Employee
實(shí)驗(yàn)35——?jiǎng)?chuàng)建單頁(yè)應(yīng)用——第三部分—新建Employee
實(shí)驗(yàn)36——?jiǎng)?chuàng)建單頁(yè)應(yīng)用——第三部分—上傳
實(shí)驗(yàn)32與其他實(shí)驗(yàn)不同,本實(shí)驗(yàn)并不是在之前實(shí)驗(yàn)基礎(chǔ)之上為程序添加新的功能,實(shí)驗(yàn)32主要目的是整理項(xiàng)目結(jié)構(gòu),使項(xiàng)目條理清晰,能夠結(jié)構(gòu)化系統(tǒng)化,便于其他人員理解。
1. 創(chuàng)建解決方案文件夾
右鍵單擊,選擇“新解決方案文件夾—>添加—>新解決方案”,命名為“View And Controller”
重復(fù)上述步驟 ,創(chuàng)建文件夾“Model”,“ViewModel”,”Data Access Layer”
2. 創(chuàng)建數(shù)據(jù)訪問層工程
右擊“Data Access Layer”文件夾,新建類庫(kù)“DataAccessLayer”。
3. 創(chuàng)建業(yè)務(wù)層和業(yè)務(wù)實(shí)體項(xiàng)
在Model文件夾下創(chuàng)建新類庫(kù)“BusinessLayer”和“BusinessEntities”
4. 創(chuàng)建ViewModel 項(xiàng)
在ViewModel 文件夾下新建類庫(kù)項(xiàng)“ViewModel“
5. 添加引用
為以上創(chuàng)建的項(xiàng)目添加引用,如下:
1. DataAccessLayer 添加 BusinessEntities項(xiàng)
2. BusinessLayer 添加DataAccessLayer和 BusinessEntities項(xiàng)
3. MVC WebApplication 選擇 BusinessLayer,BusinessEntities, ViewModel
4. BusinessEntities 添加 System.ComponentModel.DataAnnotations
6. 設(shè)置
1.將DataAccessLayer文件夾下的 SalesERPDAL.cs文件,復(fù)制粘貼到新創(chuàng)建的 DataAccessLayer 類庫(kù)中。
2. 刪除MVC項(xiàng)目(WebApplication1)的DataAccessLayer文件夾
3. 同上,將Model文件夾中的 Employee.cs, UserDetails.cs 及 UserStatus.cs文件復(fù)制到新建的 BusinessEntities文件夾中。
4. 將MVC項(xiàng)目中的Model文件夾的 EmployeeBusinessLayer.cs文件粘貼到新建的 BusinessLayer的文件夾中。
5. 刪除MVC中的Model文件夾
6. 將MVC項(xiàng)目的ViewModels文件夾下所有的文件復(fù)制到新建的ViewModel 類庫(kù)項(xiàng)中。
7. 刪除ViewModels文件夾
8. 將整個(gè)MVC項(xiàng)目剪切到”View And Controller”解決方案文件夾中。
7. Build
選擇Build->Build Solution from menu bar,會(huì)報(bào)錯(cuò)。
8. 改錯(cuò)
1. 給ViewModel項(xiàng)添加System.Web 引用
2. 在DataAccessLayer 和 BusinessLayer中使用Nuget 管理,并安裝EF(Entity Framework)(如果對(duì)于Nuget的使用有不理解的地方可以查看第三篇博客文章)
注意:在Business Layer中引用EF 是非常必要的,因?yàn)锽usiness Layer與DataAccessLayer 直接關(guān)聯(lián)的,而完善的體系架構(gòu)它自身的業(yè)務(wù)層是不應(yīng)該與DataAccessLayer直接關(guān)聯(lián),因此我們必須使用pattern庫(kù),協(xié)助完成。
3. 刪除MVC 項(xiàng)目中的EF
右擊MVC 項(xiàng)目,選擇”Manage Nuget packages“選項(xiàng)
在彈出的對(duì)話框中選擇”Installed Packages“
則會(huì)顯示所有的已安裝項(xiàng),選擇EF,點(diǎn)解卸載。
9. 編譯會(huì)發(fā)現(xiàn)還是會(huì)報(bào)錯(cuò)
10. 修改錯(cuò)誤
報(bào)錯(cuò)是由于在項(xiàng)目中既沒有引用 SalesERPDAL,也沒有引用EF,在項(xiàng)目中直接引用也并不是優(yōu)質(zhì)的解決方案。
1. 在DataAccessLayer項(xiàng)中 新建帶有靜態(tài)方法”SetDatabase“的類”DatabaseSettings“
1: using System.Data.Entity;
2: using WebApplication1.DataAccessLayer;
3: namespace DataAccessLayer
4: {
5: public class DatabaseSettings
6: {
7: public static void SetDatabase()
8: {
9: Database.SetInitializer(new DropCreateDatabaseIfModelChanges());
10: }
11: }
12: }
2. 在 BusinessLayer項(xiàng)中新建帶有”SetBusiness“ 靜態(tài)方法的”BusinessSettings“類。
1: using DataAccessLayer;
2:
3: namespace BusinessLayer
4: {
5: public class BusinessSettings
6: {
7: public static void SetBusiness()
8: {
9: DatabaseSettings.SetDatabase();
10: }
11: }
12: }
3. 刪除global.asax 中的報(bào)錯(cuò)的Using語(yǔ)句 和 Database.SetInitializer 語(yǔ)句。 調(diào)用 BusinessSettings.SetBusiness 函數(shù):
1: using BusinessLayer;
2: .
3: .
4: .
5: BundleConfig.RegisterBundles(BundleTable.Bundles);
6: BusinessSettings.SetBusiness();
再次編譯程序,會(huì)發(fā)現(xiàn)成功。
什么是解決方案文件夾?
解決方案文件夾是邏輯性的文件夾,并不是在物理磁盤上實(shí)際創(chuàng)建,這里使用解決方案文件夾就是為了使項(xiàng)目更系統(tǒng)化更有結(jié)構(gòu)。
實(shí)驗(yàn)33中,不再使用已創(chuàng)建好的控制器和視圖,會(huì)創(chuàng)建新的控制器及視圖,創(chuàng)建新控制器和視圖原因如下:
1. 保證現(xiàn)有的選項(xiàng)完整,也會(huì)用于舊版本與新版本對(duì)比
2. 學(xué)習(xí)理解ASP.NET MVC 新概念:Areas
接下來,我們需要從頭開始新建controllers, views,ViewModels。
下面的文件可以被重用:
已創(chuàng)建的業(yè)務(wù)層
已創(chuàng)建的數(shù)據(jù)訪問層
已創(chuàng)建的業(yè)務(wù)實(shí)體
授權(quán)和異常過濾器
FooterViewModel
Footer.cshtml
1. 創(chuàng)建新Area
右擊項(xiàng)目,選擇添加->Area,在彈出對(duì)話框中輸入SPA,點(diǎn)擊確認(rèn),生成新的文件夾,因?yàn)樵谠撐募A中不需要Model中Area的文件夾,刪掉。
接下來我們先了解一下Areas的概念
Areas
Areas是實(shí)現(xiàn)Asp.net MVC 項(xiàng)目模塊化管理的一種簡(jiǎn)單方法。
每個(gè)項(xiàng)目由多個(gè)模塊組成,如支付模塊,客戶關(guān)系模塊等。在傳統(tǒng)的項(xiàng)目中,采用“文件夾”來實(shí)現(xiàn)模塊化管理的,你會(huì)發(fā)現(xiàn)在單個(gè)項(xiàng)目中會(huì)有多個(gè)同級(jí)文件夾,每個(gè)文件夾代表一個(gè)模塊,并保存各模塊相關(guān)的文件。
然而,在Asp.net MVC 項(xiàng)目中使用自定義文件夾實(shí)現(xiàn)功能模塊化會(huì)導(dǎo)致很多問題。
下面是在Asp.Net MVC中使用文件夾來實(shí)現(xiàn)模塊化功能需要注意的幾點(diǎn):
DataAccessLayer, BusinessLayer, BusinessEntities和ViewModels的使用不會(huì)導(dǎo)致其他問題,在任何情況下,可視作簡(jiǎn)單的類使用。
Controllers—只能保存在Controller 文件夾,但是這不是大問題,從MVC4開始,控制器的路徑不再受限。現(xiàn)在可以放在任何文件目錄下。
所有的Views必須放在“~/Views/ControllerName” or “~/Views/Shared”文件夾。
2. 創(chuàng)建必要的ViewModels
在ViewModel類庫(kù)下新建文件夾并命名為SPA,創(chuàng)建ViewModel,命名為”MainViewModel“,如下:
1: using WebApplication1.ViewModels;
2: namespace WebApplication1.ViewModels.SPA
3: {
4: public class MainViewModel
5: {
6: public string UserName { get; set; }
7: public FooterViewModel FooterData { get; set; }//New Property
8: }
9: }
3. 創(chuàng)建Index action 方法
在 MainController 中輸入:
1: using WebApplication1.ViewModels.SPA;
2: using OldViewModel=WebApplication1.ViewModels;
在MainController 中新建Action 方法,如下:
1: public ActionResult Index()
2: {
3: MainViewModel v = new MainViewModel();
4: v.UserName = User.Identity.Name;
5: v.FooterData = new OldViewModel.FooterViewModel();
6: v.FooterData.CompanyName = "StepByStepSchools";//Can be set to dynamic value
7: v.FooterData.Year = DateTime.Now.Year.ToString();
8: return View("Index", v);
9: }
using OldViewModel=WebApplication1.ViewModels 這行代碼中,給WebApplication1.ViewModels 添加了別名OldViewModel,使用時(shí)可直接寫成OldViewModel.ClassName這種形式。
如果不定義別名的話,會(huì)產(chǎn)生歧義,因?yàn)閃ebApplication1.ViewModels.SPA 和 WebApplication1.ViewModels下有名稱相同的類。
4.創(chuàng)建Index View
創(chuàng)建與上述Index方法匹配的View
1: @using WebApplication1.ViewModels.SPA
2: @model MainViewModel
3:
4:
5:
6:
7:
8:Employee Single Page Application
5. 運(yùn)行測(cè)試
為什么在控制器名前需要使用SPA關(guān)鍵字?
在ASP.NET MVC應(yīng)用中添加area時(shí),Visual Studio會(huì)自動(dòng)創(chuàng)建并命名為“[AreaName]AreaRegistration.cs”的文件,其中包含了AreaRegistration的派生類。該類定義了 AreaName屬性和用來定義register路勁信息的 RegisterArea 方法。
在本次實(shí)驗(yàn)中你會(huì)發(fā)現(xiàn)nameSpaArealRegistration.cs文件被存放在“~/Areas/Spa”文件夾下,SpaArealRegistration類的RegisterArea方法的代碼如下:
1: context.MapRoute(
2: "SPA_default",
3: "SPA/{controller}/{action}/{id}",
4: new { action = "Index", id = UrlParameter.Optional }
5: );
這就是為什么一提到Controllers,我們會(huì)在Controllers前面加SPA關(guān)鍵字。
SPAAreaRegistration的RegisterArea方法是怎樣被調(diào)用的?
打開global.asax文件,首行代碼如下:
1: AreaRegistration.RegisterAllAreas();
RegisterAllAreas方法會(huì)找到應(yīng)用程序域中所有AreaRegistration的派生類,并主動(dòng)調(diào)用RegisterArea方法
是否可以不使用SPA關(guān)鍵字來調(diào)用MainController?
AreaRegistration類在不刪除其他路徑的同時(shí)會(huì)創(chuàng)建新路徑。RouteConfig類中定義了新路徑仍然會(huì)起作用。如之前所說的,Controller存放的路徑是不受限制的,因此它可以工作但可能不會(huì)正常的顯示,因?yàn)闊o(wú)法找到合適的View。
1.創(chuàng)建ViewModel,實(shí)現(xiàn)“顯示Empoyee”功能
在SPA中新建兩個(gè)ViewModel 類,命名為”EmployeeViewModel“及”EmployeeListViewModel“:
1: namespace WebApplication1.ViewModels.SPA
2: {
3: public class EmployeeViewModel
4: {
5: public string EmployeeName { get; set; }
6: public string Salary { get; set; }
7: public string SalaryColor { get; set; }
8: }
9: }
1: namespace WebApplication1.ViewModels.SPA
2: {
3: public class EmployeeListViewModel
4: {
5: public ListEmployees { get; set; }
6: }
7: }
8:
注意:這兩個(gè)ViewModel 都是由非SPA 應(yīng)用創(chuàng)建的,唯一的區(qū)別就在于這次不需要使用BaseViewModel。
2. 創(chuàng)建EmployeeList Index
在MainController 中創(chuàng)建新的Action 方法”EmployeeList“action 方法
1: public ActionResult EmployeeList()
2: {
3: EmployeeListViewModel employeeListViewModel = new EmployeeListViewModel();
4: EmployeeBusinessLayer empBal = new EmployeeBusinessLayer();
5: Listemployees = empBal.GetEmployees();
6:
7: ListempViewModels = new List ();
8:
9: foreach (Employee emp in employees)
10: {
11: EmployeeViewModel empViewModel = new EmployeeViewModel();
12: empViewModel.EmployeeName = emp.FirstName + " " + emp.LastName;
13: empViewModel.Salary = emp.Salary.Value.ToString("C");
14: if (emp.Salary > 15000)
15: {
16: empViewModel.SalaryColor = "yellow";
17: }
18: else
19: {
20: empViewModel.SalaryColor = "green";
21: }
22: empViewModels.Add(empViewModel);
23: }
24: employeeListViewModel.Employees = empViewModels;
25: return View("EmployeeList", employeeListViewModel);
26: }
27:
注意: 不需要使用 HeaderFooterFilter
3. 創(chuàng)建AddNewLink 分部View
之前添加AddNewLink 分部View已經(jīng)無(wú)法使用,因?yàn)锳nchor標(biāo)簽會(huì)造成全局刷新,我們的目標(biāo)是創(chuàng)建”單頁(yè)應(yīng)用“,因此不需要全局刷新。
在”~/Areas/Spa/Views/Main“ 文件夾新建分部View”AddNewLink.cshtml“。
1: Add New
4. 創(chuàng)建 AddNewLink Action 方法
在MainController中創(chuàng)建 ”GetAddNewLink“ action 方法。
1: public ActionResult GetAddNewLink()
2: {
3: if (Convert.ToBoolean(Session["IsAdmin"]))
4: {
5: return PartialView("AddNewLink");
6: }
7: else
8: {
9: return new EmptyResult();
10: }
11: }
5. 新建 EmployeeList View
在“~/Areas/Spa/Views/Main”中創(chuàng)建新分部View 命名為“EmployeeList”。
1: @using WebApplication1.ViewModels.SPA
2: @model EmployeeListViewModel
3:4: @{5: Html.RenderAction("GetAddNewLink");6: }7:8:
9: 10:Employee Name 6. 設(shè)置EmployeeList 為初始頁(yè)面
打開“~/Areas/Spa/Views/Main/Index.cshtml”文件,在Div標(biāo)簽內(nèi)包含EmployeeList action結(jié)果。
1: ...2:7. 運(yùn)行
實(shí)驗(yàn) 35——?jiǎng)?chuàng)建單頁(yè)應(yīng)用3—?jiǎng)?chuàng)建Employee
1. 創(chuàng)建AddNew ViewModels
在SPA中新建 ViewModel類庫(kù)項(xiàng)的ViewModel,命名為“CreateEmployeeViewModel”。
1: namespace WebApplication1.ViewModels.SPA2: {3: public class CreateEmployeeViewModel4: {5: public string FirstName { get; set; }6: public string LastName { get; set; }7: public string Salary { get; set; }8: }9: }2. 創(chuàng)建AddNew action 方法
在MainController中輸入using 語(yǔ)句:
1: using WebApplication1.Filters;在MainController 中創(chuàng)建AddNew action 方法:
1: [AdminFilter]2: public ActionResult AddNew()3: {4: CreateEmployeeViewModel v = new CreateEmployeeViewModel();5: return PartialView("CreateEmployee", v);6: }3. 創(chuàng)建 CreateEmployee 分部View
在“~/Areas/Spa/Views/Main”中創(chuàng)建新的分部View“CreateEmployee”
1: @using WebApplication1.ViewModels.SPA2: @model CreateEmployeeViewModel3:4:
5: 6: 7: First Name:8:4. 添加 jQuery UI
右擊項(xiàng)目選擇“Manage Nuget Manager”。找到“jQuery UI”并安裝。
項(xiàng)目中會(huì)自動(dòng)添加.js和.css文件
5. 在項(xiàng)目中添加jQuery UI
打開“~/Areas/Spa/Views/Main/Index.cshtml”,添加jQuery.js,jQueryUI.js 及所有的.css文件的引用。這些文件會(huì)通過Nuget Manager添加到j(luò)Query UI 包中。
1:2:3:4:5:Employee Single Page Application 6:7: ...6. 實(shí)現(xiàn) OpenAddNew 方法
在“~/Areas/Spa/Views/Main/Index.cshtml”中新建JavaScript方法“OpenAddNew”。
1:2: function OpenAddNew() {3: $.get("/SPA/Main/AddNew").then4: (5: function (r) {6: $("").html(r).7: dialog({8: width: 'auto', height: 'auto', modal: true, title: "Create New Employee",9: close: function () {10: $('#DivCreateEmployee').remove();11: }12: });13: }14: );15: }16:7. 運(yùn)行
完成登錄步驟后導(dǎo)航到Index中,點(diǎn)擊Add New 鏈接。
8. 創(chuàng)建 ResetForm 方法
在CreateEmployee.cshtml頂部,輸入以下代碼,創(chuàng)建ResetForm函數(shù):
1: @model CreateEmployeeViewModel2:3: function ResetForm() {4: document.getElementById('TxtFName').value = "";5: document.getElementById('TxtLName').value = "";6: document.getElementById('TxtSalary').value = "";7: }8:9. 創(chuàng)建 CancelSave 方法
在CreateEmployee.cshtml頂部,輸入以下代碼,創(chuàng)建CancelSave 函數(shù):
1: document.getElementById('TxtSalary').value = "";2: }3: function CancelSave() {4: $('#DivCreateEmployee').dialog('close');5: }在開始下一步驟之前,我們先來了解我們將實(shí)現(xiàn)的功能:
最終用戶點(diǎn)擊保存按鈕
輸入值必須在客戶端完成驗(yàn)證
會(huì)將合法值傳到服務(wù)器端
新Employee記錄必須保存到數(shù)據(jù)庫(kù)中
CreateEmployee對(duì)話框使用完成之后必須關(guān)閉
插入新值后,需要更新表格。
為了實(shí)現(xiàn)三大功能,先確定一些實(shí)現(xiàn)計(jì)劃:
1.驗(yàn)證
驗(yàn)證功能可以使用之前項(xiàng)目的驗(yàn)證代碼。
2.保存功能
我們會(huì)創(chuàng)建新的MVC action 方法實(shí)現(xiàn)保存Employee,并使用jQuery Ajax調(diào)用
3. 服務(wù)器端與客戶端進(jìn)行數(shù)據(jù)通信
在之前的實(shí)驗(yàn)中,使用Form標(biāo)簽和提交按鈕來輔助完成的,現(xiàn)在由于使用這兩種功能會(huì)導(dǎo)致全局刷新,因此我們將使用jQuery Ajax方法來替代Form標(biāo)簽和提交按鈕。
尋求解決方案
1. 理解問題
大家會(huì)疑惑JavaScript和Asp.NET 是兩種技術(shù),如何進(jìn)行數(shù)據(jù)交互?
解決方案: 通用數(shù)據(jù)類型
由于這兩種技術(shù)都支持如int,float等等數(shù)據(jù)類型,盡管他們的存儲(chǔ)方式,大小不同,但是在行業(yè)總有一種數(shù)據(jù)類型能夠處理任何數(shù)據(jù),稱之為最兼容數(shù)據(jù)類型即字符串類型。
通用的解決方案就是將所有數(shù)據(jù)轉(zhuǎn)換為字符串類型,因?yàn)闊o(wú)論哪種技術(shù)都支持且能理解字符串類型的數(shù)據(jù)。
問題:復(fù)雜數(shù)據(jù)該怎么傳遞?
.net中的復(fù)雜數(shù)據(jù)通常指的是類和對(duì)象,這一類數(shù)據(jù),.net與其他技術(shù)傳遞復(fù)雜數(shù)據(jù)就意味著傳類對(duì)象的數(shù)據(jù),從JavaScript給其他技術(shù)傳的復(fù)雜類型數(shù)據(jù)就是JavaScript對(duì)象。因此是不可能直接傳遞的,因此我們需要將對(duì)象類型的數(shù)據(jù)轉(zhuǎn)換為標(biāo)準(zhǔn)的字符串類型,然后再發(fā)送。
解決方案—標(biāo)準(zhǔn)的通用數(shù)據(jù)格式
可以使用XML定義一種通用的數(shù)據(jù)格式,因?yàn)槊糠N技術(shù)都需要將數(shù)據(jù)轉(zhuǎn)換為XML格式的字符串,來與其他技術(shù)通信,跟字符串類型一樣,XML是每種技術(shù)都會(huì)考慮的一種標(biāo)準(zhǔn)格式。
如下,用C#創(chuàng)建的Employee對(duì)象,可以用XML 表示為:
1:2:Sukesh 3: Mumbai4:因此可選的解決方案就是,將技術(shù)1中的復(fù)雜數(shù)據(jù)轉(zhuǎn)換為XML格式的字符串,然再發(fā)送給技術(shù)2.
然而使用XML格式可能會(huì)導(dǎo)致數(shù)據(jù)占用的字節(jié)數(shù)太多,不易發(fā)送。數(shù)據(jù)SiZE越大意味著性能越低效。還有就是XML的創(chuàng)建和解析比較困難。
為了處理XML創(chuàng)建和解析的問題,使用JSON格式,全稱“JavaScript Object Notation”。
C#創(chuàng)建的Employee對(duì)象用JSON表示:
1: {2: EmpName: "Sukesh",3: Address: "Mumbai"4: }JSON數(shù)據(jù)是相對(duì)輕量級(jí)的數(shù)據(jù)類型,且JAVASCRIPT提供轉(zhuǎn)換和解析JSON格式的功能函數(shù)。
1: var e={2: EmpName= “Sukesh”,3: Address= “Mumbai”4: };5: var EmployeeJsonString = JSON.stringify(e);//This EmployeeJsonString will be send to other technologies.1: var EmployeeJsonString=GetFromOtherTechnology();2: var e=JSON.parse(EmployeeJsonString);3: alert(e.EmpName);4: alert(e.Address);數(shù)據(jù)傳輸?shù)膯栴}解決了,讓我們繼續(xù)進(jìn)行實(shí)驗(yàn)。
10. 創(chuàng)建 SaveEmployee action
在MainController中創(chuàng)建action,如下:
1: [AdminFilter]2: public ActionResult SaveEmployee(Employee emp)3: {4: EmployeeBusinessLayer empBal = new EmployeeBusinessLayer();5: empBal.SaveEmployee(emp);6:7: EmployeeViewModel empViewModel = new EmployeeViewModel();8: empViewModel.EmployeeName = emp.FirstName + " " + emp.LastName;9: empViewModel.Salary = emp.Salary.Value.ToString("C");10: if (emp.Salary > 15000)11: {12: empViewModel.SalaryColor = "yellow";13: }14: else15: {16: empViewModel.SalaryColor = "green";17: }18: return Json(empViewModel);19: }上述代碼中,使用Json方法在MVC action方法到JavaScript之間傳Json字符串。
11. 添加 Validation.js 引用
1: @using WebApplication1.ViewModels.SPA2: @model CreateEmployeeViewModel3:12. 創(chuàng)建 SaveEmployee 方法
在CreateEmployee.cshtml View中,創(chuàng)建 SaveEmployee方法:
1: ...2: ...3:4: function SaveEmployee() {5: if (IsValid()) {6: var e =7: {8: FirstName: $('#TxtFName').val(),9: LastName: $('#TxtLName').val(),10: Salary: $('#TxtSalary').val()11: };12: $.post("/SPA/Main/SaveEmployee",e).then(13: function (r) {14: var newTr = $(''); 15: var nameTD = $(''); 16: var salaryTD = $(''); 17:18: nameTD.text(r.EmployeeName);19: salaryTD.text(r.Salary);20:21: salaryTD.css("background-color", r.SalaryColor);22:23: newTr.append(nameTD);24: newTr.append(salaryTD);25:26: $('#EmployeeTable').append(newTr);27: $('#DivCreateEmployee').dialog('close');28: }29: );30: }31: }32:13. 運(yùn)行
關(guān)于實(shí)驗(yàn)35
JSON 方法的作用是什么?
返回JSONResult,JSONResult 是ActionResult 的子類。在第六篇博客中講過MVC的請(qǐng)求周期。
ExecuteResult是ActionResult中聲明的抽象方法,ActionResult所有的子類都定義了該方法。在第一篇博客中我們已經(jīng)講過ViewResult 的ExecuteResult方法實(shí)現(xiàn)的功能,有什么不理解的可以翻看第一篇博客。
實(shí)驗(yàn)36——?jiǎng)?chuàng)建單頁(yè)應(yīng)用—4—批量上傳
1. 創(chuàng)建SpaBulkUploadController
創(chuàng)建新的AsyncController“ SpaBulkUploadController”
1: namespace WebApplication1.Areas.SPA.Controllers2: {3: public class SpaBulkUploadController : AsyncController4: {5: }6: }2. 創(chuàng)建Index Action
在步驟1中的Controller中創(chuàng)建新的Index Action 方法,如下:
1: [AdminFilter]2: public ActionResult Index()3: {4: return PartialView("Index");5: }3. 創(chuàng)建Index 分部View
在“~/Areas/Spa/Views/SpaBulkUpload”中創(chuàng)建 Index分部View
1:2: Select File :3:4:4. 創(chuàng)建 OpenBulkUpload 方法
打開“~/Areas/Spa/Views/Main/Index.cshtml”文件,新建JavaScript 方法OpenBulkUpload
1: function OpenBulkUpload() {2: $.get("/SPA/SpaBulkUpload/Index").then3: (4: function (r) {5: $("").html(r).dialog({ width: 'auto', height: 'auto', modal: true, title: "Create New Employee",6: close: function () {7: $('#DivBulkUpload').remove();8: } });9: }10: );11: }12:13:14:15:5. 運(yùn)行
6. 新建FileUploadViewModel
在ViewModel SPA文件夾中新建View Model”FileUploadViewModel”。
1: namespace WebApplication1.ViewModels.SPA2: {3: public class FileUploadViewModel4: {5: public HttpPostedFileBase fileUpload { get; set; }6: }7: }7. 創(chuàng)建Upload Action
1: [AdminFilter]2: public async TaskUpload(FileUploadViewModel model) 3: {4: int t1 = Thread.CurrentThread.ManagedThreadId;5: Listemployees = await Task.Factory.StartNew >
6: (() => GetEmployees(model));7: int t2 = Thread.CurrentThread.ManagedThreadId;8: EmployeeBusinessLayer bal = new EmployeeBusinessLayer();9: bal.UploadEmployees(employees);10: EmployeeListViewModel vm = new EmployeeListViewModel();11: vm.Employees = new List(); 12: foreach (Employee item in employees)13: {14: EmployeeViewModel evm = new EmployeeViewModel();15: evm.EmployeeName = item.FirstName + " " + item.LastName;16: evm.Salary = item.Salary.Value.ToString("C");17: if (item.Salary > 15000)18: {19: evm.SalaryColor = "yellow";20: }21: else22: {23: evm.SalaryColor = "green";24: }25: vm.Employees.Add(evm);26: }27: return Json(vm);28: }29:30: private ListGetEmployees(FileUploadViewModel model) 31: {32: Listemployees = new List (); 33: StreamReader csvreader = new StreamReader(model.fileUpload.InputStream);34: csvreader.ReadLine();// Assuming first line is header35: while (!csvreader.EndOfStream)36: {37: var line = csvreader.ReadLine();38: var values = line.Split(',');//Values are comma separated39: Employee e = new Employee();40: e.FirstName = values[0];41: e.LastName = values[1];42: e.Salary = int.Parse(values[2]);43: employees.Add(e);44: }45: return employees;46: }47:8. 創(chuàng)建Upload 函數(shù)
打開”~/Areas/Spa/Views/SpaBulkUpload”的Index View。創(chuàng)建JavaScript函數(shù),命名為“Upload”
1:2: function Upload() {3: debugger;4: var fd = new FormData();5: var file = $('#MyFileUploader')[0];6: fd.append("fileUpload", file.files[0]);7: $.ajax({8: url: "/Spa/SpaBulkUpload/Upload",9: type: 'POST',10: contentType: false,11: processData: false,12: data: fd13: }).then(function (e) {14: debugger;15: for (i = 0; i < e.Employees.length; i++)16: {17: var newTr = $(''); 18: var nameTD = $(''); 19: var salaryTD = $(''); 20:21: nameTD.text(e.Employees[i].EmployeeName);22: salaryTD.text(e.Employees[i].Salary);23:24: salaryTD.css("background-color", e.Employees[i].SalaryColor);25:26: newTr.append(nameTD);27: newTr.append(salaryTD);28:29: $('#EmployeeTable').append(newTr);30: }31: $('#DivBulkUpload').dialog('close');32: });33: }34:9. 運(yùn)行
總結(jié)
七天學(xué)會(huì)MVC 就到這里結(jié)束了,謝謝大家的支持,希望大家都能夠掌握所講述的MVC知識(shí),希望都能夠進(jìn)步!
原文鏈接:http://www.codeproject.com/Articles/1010152/Learn-MVC-Project-in-Days-Day
網(wǎng)頁(yè)標(biāo)題:七天學(xué)會(huì)ASP.NETMVC(七)——?jiǎng)?chuàng)建單頁(yè)應(yīng)用
分享網(wǎng)址:http://weahome.cn/article/jghjhs.html其他資訊