七天學會ASP.NET MVC(七)——創建單頁應用

目錄

  • 引言
  • 最後一篇學什麼
  • 實驗32—整理項目組織結構
  • 關於實驗32
  • 實驗33——創建單頁應用——第一部分—安裝
  • 什麼是Areas?
  • 關於實驗33
  • 實驗34——創建單頁應用——第二部分—顯示Employee
  • 實驗35——創建單頁應用——第三部分—新建Employee
  • 實驗36——創建單頁應用——第三部分—上傳

 

實驗32 ———整理項目組織結構

實驗32與其他實驗不同,本實驗並不是在之前實驗基礎之上爲程序添加新的功能,實驗32主要目的是整理項目結構,使項目條理清晰,能夠結構化系統化,便於其他人員理解。

1. 創建解決方案文件夾

右鍵單擊,選擇“新解決方案文件夾—>添加—>新解決方案”,命名爲“View And Controller”

 

重複上述步驟 ,創建文件夾“Model”,“ViewModel”,”Data Access Layer”

2. 創建數據訪問層工程

右擊“Data Access Layer”文件夾,新建類庫“DataAccessLayer”。

3. 創建業務層和業務實體項

在Model文件夾下創建新類庫“BusinessLayer”和“BusinessEntities”

4. 創建ViewModel 項

在ViewModel 文件夾下新建類庫項“ViewModel“

5. 添加引用

爲以上創建的項目添加引用,如下:

1. DataAccessLayer 添加 BusinessEntities項

2. BusinessLayer 添加DataAccessLayer和 BusinessEntities項

3. MVC WebApplication 選擇 BusinessLayer,BusinessEntities, ViewModel

4. BusinessEntities 添加 System.ComponentModel.DataAnnotations

6. 設置

1.將DataAccessLayer文件夾下的 SalesERPDAL.cs文件,複製粘貼到新創建的 DataAccessLayer 類庫中。

 

2. 刪除MVC項目(WebApplication1)的DataAccessLayer文件夾 
3. 同上,將Model文件夾中的 Employee.cs, UserDetails.cs 及 UserStatus.cs文件複製到新建的 BusinessEntities文件夾中。

4. 將MVC項目中的Model文件夾的 EmployeeBusinessLayer.cs文件粘貼到新建的 BusinessLayer的文件夾中。

5. 刪除MVC中的Model文件夾

6. 將MVC項目的ViewModels文件夾下所有的文件複製到新建的ViewModel 類庫項中。

7. 刪除ViewModels文件夾

8. 將整個MVC項目剪切到”View And Controller”解決方案文件夾中。

 

7. Build

選擇Build->Build Solution from menu bar,會報錯。

8. 改錯

1. 給ViewModel項添加System.Web 引用

2. 在DataAccessLayer 和 BusinessLayer中使用Nuget 管理,並安裝EF(Entity Framework)(如果對於Nuget的使用有不理解的地方可以查看第三篇博客文章

注意:在Business Layer中引用EF 是非常必要的,因爲Business Layer與DataAccessLayer 直接關聯的,而完善的體系架構它自身的業務層是不應該與DataAccessLayer直接關聯,因此我們必須使用pattern庫,協助完成。

3. 刪除MVC 項目中的EF

  • 右擊MVC 項目,選擇”Manage Nuget packages“選項
  • 在彈出的對話框中選擇”Installed Packages“
  • 則會顯示所有的已安裝項,選擇EF,點解卸載。

9. 編譯會發現還是會報錯

10. 修改錯誤

報錯是由於在項目中既沒有引用 SalesERPDAL,也沒有引用EF,在項目中直接引用也並不是優質的解決方案。

1. 在DataAccessLayer項中 新建帶有靜態方法”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<SalesERPDAL>());<saleserpdal>
  10:          }
  11:      }    
  12:  }
 

2. 在 BusinessLayer項中新建帶有”SetBusiness“ 靜態方法的”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 中的報錯的Using語句 和 Database.SetInitializer 語句。 調用 BusinessSettings.SetBusiness 函數:

   1:  using BusinessLayer;
   2:  .
   3:  .
   4:  .
   5:  BundleConfig.RegisterBundles(BundleTable.Bundles);
   6:  BusinessSettings.SetBusiness();

再次編譯程序,會發現成功。

關於實驗32

什麼是解決方案文件夾?

解決方案文件夾是邏輯性的文件夾,並不是在物理磁盤上實際創建,這裏使用解決方案文件夾就是爲了使項目更系統化更有結構。

實驗33——創建單頁應用 1—安裝

實驗33中,不再使用已創建好的控制器和視圖,會創建新的控制器及視圖,創建新控制器和視圖原因如下:

1. 保證現有的選項完整,也會用於舊版本與新版本對比 
2. 學習理解ASP.NET MVC 新概念:Areas

接下來,我們需要從頭開始新建controllers, views,ViewModels。

下面的文件可以被重用:

  • 已創建的業務層
  • 已創建的數據訪問層
  • 已創建的業務實體
  • 授權和異常過濾器
  • FooterViewModel
  • Footer.cshtml

 

1. 創建新Area

右擊項目,選擇添加->Area,在彈出對話框中輸入SPA,點擊確認,生成新的文件夾,因爲在該文件夾中不需要Model中Area的文件夾,刪掉。

接下來我們先了解一下Areas的概念

Areas

Areas是實現Asp.net MVC 項目模塊化管理的一種簡單方法。

每個項目由多個模塊組成,如支付模塊,客戶關係模塊等。在傳統的項目中,採用“文件夾”來實現模塊化管理的,你會發現在單個項目中會有多個同級文件夾,每個文件夾代表一個模塊,並保存各模塊相關的文件。

然而,在Asp.net MVC 項目中使用自定義文件夾實現功能模塊化會導致很多問題。

下面是在Asp.Net MVC中使用文件夾來實現模塊化功能需要注意的幾點:

  • DataAccessLayer, BusinessLayer, BusinessEntities和ViewModels的使用不會導致其他問題,在任何情況下,可視作簡單的類使用。
  • Controllers—只能保存在Controller 文件夾,但是這不是大問題,從MVC4開始,控制器的路徑不再受限。現在可以放在任何文件目錄下。
  • 所有的Views必須放在“~/Views/ControllerName” or “~/Views/Shared”文件夾。

 

2. 創建必要的ViewModels

在ViewModel類庫下新建文件夾並命名爲SPA,創建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. 創建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,使用時可直接寫成OldViewModel.ClassName這種形式。

如果不定義別名的話,會產生歧義,因爲WebApplication1.ViewModels.SPA 和 WebApplication1.ViewModels下有名稱相同的類。

4.創建Index View

創建與上述Index方法匹配的View

   1:  @using WebApplication1.ViewModels.SPA
   2:  @model MainViewModel
   3:  <!DOCTYPE html>
   4:   
   5:  <html>
   6:  <head>
   7:      <meta name="viewport" content="width=device-width" />
   8:      <title>Employee Single Page Application</title>

5. 運行測試

關於實驗33

爲什麼在控制器名前需要使用SPA關鍵字?

在ASP.NET MVC應用中添加area時,Visual Studio會自動創建並命名爲“[AreaName]AreaRegistration.cs”的文件,其中包含了AreaRegistration的派生類。該類定義了 AreaName屬性和用來定義register路勁信息的 RegisterArea 方法。

在本次實驗中你會發現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,我們會在Controllers前面加SPA關鍵字。

 

SPAAreaRegistration的RegisterArea方法是怎樣被調用的?

打開global.asax文件,首行代碼如下:

   1:  AreaRegistration.RegisterAllAreas();

RegisterAllAreas方法會找到應用程序域中所有AreaRegistration的派生類,並主動調用RegisterArea方法

是否可以不使用SPA關鍵字來調用MainController?

AreaRegistration類在不刪除其他路徑的同時會創建新路徑。RouteConfig類中定義了新路徑仍然會起作用。如之前所說的,Controller存放的路徑是不受限制的,因此它可以工作但可能不會正常的顯示,因爲無法找到合適的View。

實驗34——創建單頁應用2—顯示Employees

1.創建ViewModel,實現“顯示Empoyee”功能

在SPA中新建兩個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 List<employeeviewmodel> Employees { get; set; }
   6:      }
   7:  }
   8:  </employeeviewmodel>

注意:這兩個ViewModel 都是由非SPA 應用創建的,唯一的區別就在於這次不需要使用BaseViewModel。

2. 創建EmployeeList Index

在MainController 中創建新的Action 方法”EmployeeList“action 方法

   1:  public ActionResult EmployeeList()
   2:  {
   3:      EmployeeListViewModel employeeListViewModel = new EmployeeListViewModel();
   4:      EmployeeBusinessLayer empBal = new EmployeeBusinessLayer();
   5:      List<employee> employees = empBal.GetEmployees();
   6:   
   7:      List<employeeviewmodel> empViewModels = new List<employeeviewmodel>();
   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:  </employeeviewmodel>

注意: 不需要使用 HeaderFooterFilter

3. 創建AddNewLink 分部View

之前添加AddNewLink 分部View已經無法使用,因爲Anchor標籤會造成全局刷新,我們的目標是創建”單頁應用“,因此不需要全局刷新。

在”~/Areas/Spa/Views/Main“ 文件夾新建分部View”AddNewLink.cshtml“。

   1:  <a href="#" onclick="OpenAddNew();">Add New</a>

4. 創建 AddNewLink Action 方法

在MainController中創建 ”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”中創建新分部View 命名爲“EmployeeList”。

   1:  @using WebApplication1.ViewModels.SPA
   2:  @model EmployeeListViewModel
   3:  <div>
   4:      @{
   5:          Html.RenderAction("GetAddNewLink");
   6:      }
   7:   
   8:      <table border="1" id="EmployeeTable">
   9:          <tr>
  10:              <th>Employee Name</th>

6. 設置EmployeeList 爲初始頁面

打開“~/Areas/Spa/Views/Main/Index.cshtml”文件,在Div標籤內包含EmployeeList action結果。

   1:  ...  
   2:  </div>

7. 運行

實驗 35——創建單頁應用3—創建Employee

1. 創建AddNew ViewModels

在SPA中新建 ViewModel類庫項的ViewModel,命名爲“CreateEmployeeViewModel”。

   1:  namespace WebApplication1.ViewModels.SPA
   2:  {
   3:      public class CreateEmployeeViewModel
   4:      {
   5:          public string FirstName { get; set; }
   6:          public string LastName { get; set; }
   7:          public string Salary { get; set; }
   8:      }
   9:  }

2. 創建AddNew action 方法

在MainController中輸入using 語句:

   1:  using WebApplication1.Filters;

在MainController 中創建AddNew action 方法:

   1:  [AdminFilter]
   2:  public ActionResult AddNew()
   3:  {
   4:      CreateEmployeeViewModel v = new CreateEmployeeViewModel();
   5:      return PartialView("CreateEmployee", v);
   6:  }

3. 創建 CreateEmployee 分部View

在“~/Areas/Spa/Views/Main”中創建新的分部View“CreateEmployee”

   1:  @using WebApplication1.ViewModels.SPA
   2:  @model CreateEmployeeViewModel
   3:  <div>
   4:      <table>
   5:          <tr>
   6:              <td>
   7:                  First Name:
   8:              </td>

4. 添加 jQuery UI

右擊項目選擇“Manage Nuget Manager”。找到“jQuery UI”並安裝。

項目中會自動添加.js和.css文件

5. 在項目中添加jQuery UI

打開“~/Areas/Spa/Views/Main/Index.cshtml”,添加jQuery.js,jQueryUI.js 及所有的.css文件的引用。這些文件會通過Nuget Manager添加到jQuery UI 包中。

   1:  <head>
   2:  <meta name="viewport" content="width=device-width" />
   3:  <script src="~/Scripts/jquery-1.8.0.js"></script>
   4:  <script src="~/Scripts/jquery-ui-1.11.4.js"></script>
   5:  <title>Employee Single Page Application</title>
   6:  <link href="~/Content/themes/base/all.css" rel="stylesheet" />
   7:  ...

6. 實現 OpenAddNew 方法

在“~/Areas/Spa/Views/Main/Index.cshtml”中新建JavaScript方法“OpenAddNew”。

   1:  <script>
   2:      function OpenAddNew() {
   3:          $.get("/SPA/Main/AddNew").then
   4:              (
   5:                  function (r) {
   6:                      $("<div id='DivCreateEmployee'></div>").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:  </script>

7. 運行

完成登錄步驟後導航到Index中,點擊Add New 鏈接。

8. 創建 ResetForm 方法

在CreateEmployee.cshtml頂部,輸入以下代碼,創建ResetForm函數:

   1:  @model CreateEmployeeViewModel
   2:  <script>
   3:      function ResetForm() {
   4:          document.getElementById('TxtFName').value = "";
   5:          document.getElementById('TxtLName').value = "";
   6:          document.getElementById('TxtSalary').value = "";
   7:      }
   8:  </script>

9. 創建 CancelSave 方法

在CreateEmployee.cshtml頂部,輸入以下代碼,創建CancelSave 函數:

   1:  document.getElementById('TxtSalary').value = "";
   2:      }
   3:      function CancelSave() {
   4:          $('#DivCreateEmployee').dialog('close');
   5:      }

在開始下一步驟之前,我們先來了解我們將實現的功能:

  • 最終用戶點擊保存按鈕
  • 輸入值必須在客戶端完成驗證
  • 會將合法值傳到服務器端
  • 新Employee記錄必須保存到數據庫中
  • CreateEmployee對話框使用完成之後必須關閉
  • 插入新值後,需要更新表格。

爲了實現三大功能,先確定一些實現計劃:

1.驗證

驗證功能可以使用之前項目的驗證代碼。

2.保存功能

我們會創建新的MVC action 方法實現保存Employee,並使用jQuery Ajax調用

3. 服務器端與客戶端進行數據通信

在之前的實驗中,使用Form標籤和提交按鈕來輔助完成的,現在由於使用這兩種功能會導致全局刷新,因此我們將使用jQuery Ajax方法來替代Form標籤和提交按鈕。

尋求解決方案

1. 理解問題

大家會疑惑JavaScript和Asp.NET 是兩種技術,如何進行數據交互?

解決方案: 通用數據類型

由於這兩種技術都支持如int,float等等數據類型,儘管他們的存儲方式,大小不同,但是在行業總有一種數據類型能夠處理任何數據,稱之爲最兼容數據類型即字符串類型。

通用的解決方案就是將所有數據轉換爲字符串類型,因爲無論哪種技術都支持且能理解字符串類型的數據。

 

問題:複雜數據該怎麼傳遞?

.net中的複雜數據通常指的是類和對象,這一類數據,.net與其他技術傳遞複雜數據就意味着傳類對象的數據,從JavaScript給其他技術傳的複雜類型數據就是JavaScript對象。因此是不可能直接傳遞的,因此我們需要將對象類型的數據轉換爲標準的字符串類型,然後再發送。

解決方案—標準的通用數據格式

可以使用XML定義一種通用的數據格式,因爲每種技術都需要將數據轉換爲XML格式的字符串,來與其他技術通信,跟字符串類型一樣,XML是每種技術都會考慮的一種標準格式。

如下,用C#創建的Employee對象,可以用XML 表示爲:

   1:  <employee></employee><Employee>
   2:        <EmpName>Sukesh</EmpName>
   3:        <Address>Mumbai</Address>
   4:  </Employee>

因此可選的解決方案就是,將技術1中的複雜數據轉換爲XML格式的字符串,然再發送給技術2.

然而使用XML格式可能會導致數據佔用的字節數太多,不易發送。數據SiZE越大意味着性能越低效。還有就是XML的創建和解析比較困難。

爲了處理XML創建和解析的問題,使用JSON格式,全稱“JavaScript Object Notation”。

C#創建的Employee對象用JSON表示:

   1:  {
   2:    EmpName: "Sukesh",
   3:    Address: "Mumbai"
   4:  }

JSON數據是相對輕量級的數據類型,且JAVASCRIPT提供轉換和解析JSON格式的功能函數。

   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);

數據傳輸的問題解決了,讓我們繼續進行實驗。

10. 創建 SaveEmployee action

在MainController中創建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:  else
  15:  {
  16:  empViewModel.SalaryColor = "green";
  17:      }
  18:  return Json(empViewModel);
  19:  }

上述代碼中,使用Json方法在MVC action方法到JavaScript之間傳Json字符串。

11. 添加 Validation.js 引用

   1:  @using WebApplication1.ViewModels.SPA
   2:  @model CreateEmployeeViewModel
   3:  <script src="~/Scripts/Validations.js"></script>

12. 創建 SaveEmployee 方法

在CreateEmployee.cshtml View中,創建 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 = $('<tr></tr>');
  15:                      var nameTD = $('<td></td>');
  16:                      var salaryTD = $('<td></td>');
  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:  </script>

13. 運行

關於實驗35

JSON 方法的作用是什麼?

返回JSONResult,JSONResult 是ActionResult 的子類。在第六篇博客中講過MVC的請求週期。

ExecuteResult是ActionResult中聲明的抽象方法,ActionResult所有的子類都定義了該方法。在第一篇博客中我們已經講過ViewResult 的ExecuteResult方法實現的功能,有什麼不理解的可以翻看第一篇博客。

實驗36——創建單頁應用—4—批量上傳

1. 創建SpaBulkUploadController

創建新的AsyncController“ SpaBulkUploadController”

   1:  namespace WebApplication1.Areas.SPA.Controllers
   2:  {
   3:      public class SpaBulkUploadController : AsyncController
   4:      {
   5:      }
   6:  }

2. 創建Index Action

在步驟1中的Controller中創建新的Index Action 方法,如下:

   1:  [AdminFilter]
   2:  public ActionResult Index()
   3:  {
   4:      return PartialView("Index");
   5:  }

3. 創建Index 分部View

在“~/Areas/Spa/Views/SpaBulkUpload”中創建 Index分部View

   1:  <div>
   2:      Select File : <input type="file" name="fileUpload" id="MyFileUploader" value="" />
   3:      <input type="submit" name="name" value="Upload" onclick="Upload();" />
   4:  </div>

4. 創建 OpenBulkUpload  方法

打開“~/Areas/Spa/Views/Main/Index.cshtml”文件,新建JavaScript 方法OpenBulkUpload

   1:  function OpenBulkUpload() {
   2:              $.get("/SPA/SpaBulkUpload/Index").then
   3:                  (
   4:                  function (r) {
   5:       $("<div id='DivBulkUpload'></div>").html(r).dialog({ width: 'auto', height: 'auto', modal: true, title: "Create New Employee",
   6:                              close: function () {
   7:                                  $('#DivBulkUpload').remove();
   8:                              } });
   9:                      }
  10:                  );
  11:          }
  12:      </script>
  13:  </head>
  14:  <body>
  15:      <div style="text-align:right">

5. 運行

6. 新建FileUploadViewModel

在ViewModel SPA文件夾中新建View Model”FileUploadViewModel”。

   1:  namespace WebApplication1.ViewModels.SPA
   2:  {
   3:      public class FileUploadViewModel
   4:      {
   5:          public HttpPostedFileBase fileUpload { get; set; }
   6:      }
   7:  }

7. 創建Upload Action

   1:  [AdminFilter]
   2:  public async Task<actionresult> Upload(FileUploadViewModel model)
   3:  {
   4:      int t1 = Thread.CurrentThread.ManagedThreadId;
   5:      List<employee> employees = await Task.Factory.StartNew<list<employee>>
   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<employeeviewmodel>();
  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:          else
  22:          {
  23:              evm.SalaryColor = "green";
  24:          }
  25:          vm.Employees.Add(evm);
  26:      }
  27:      return Json(vm);
  28:  }
  29:   
  30:  private List<employee> GetEmployees(FileUploadViewModel model)
  31:  {
  32:      List<employee> employees = new List<employee>();
  33:      StreamReader csvreader = new StreamReader(model.fileUpload.InputStream);
  34:      csvreader.ReadLine();// Assuming first line is header
  35:      while (!csvreader.EndOfStream)
  36:      {
  37:          var line = csvreader.ReadLine();
  38:          var values = line.Split(',');//Values are comma separated
  39:          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:  </employee>

8. 創建Upload 函數

打開”~/Areas/Spa/Views/SpaBulkUpload”的Index View。創建JavaScript函數,命名爲“Upload”

   1:  <script>
   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: fd
  13:          }).then(function (e) {
  14:              debugger;
  15:              for (i = 0; i < e.Employees.length; i++)
  16:              {
  17:                  var newTr = $('<tr></tr>');
  18:                  var nameTD = $('<td></td>');
  19:                  var salaryTD = $('<td></td>');
  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:  </script>

9. 運行

總結

以上本系列的七篇文章就是介紹MVC知識的全部內容了,看到這裏你是否已經對MVC的知識有了較爲全面的掌握?在具備MVC知識的同時,使用一些開發工具將會使我們的開發過程變得事半功倍,藉助 ComponentOne Studio ASP.NET MVC 這款輕量級控件,開發效率大大提高的同時,工作量也會大大減少。

七天學會MVC 就到這裏結束了,謝謝大家的支持,希望大家都能夠掌握所講述的MVC知識,希望都能夠進步!

原文鏈接:http://www.codeproject.com/Articles/1010152/Learn-MVC-Project-in-Days-Day

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章