溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

七天學(xué)會ASP.NET MVC(七)——?jiǎng)?chuàng)建單頁應(yīng)用

發(fā)布時(shí)間:2020-07-25 15:00:16 來源:網(wǎng)絡(luò) 閱讀:531 作者:powertoolsteam 欄目:編程語言
七天學(xué)會ASP.NET MVC(七)——?jiǎng)?chuàng)建單頁應(yīng)用
系列文章

七天學(xué)會ASP.NET MVC (一)——深入理解ASP.NET MVC

七天學(xué)會ASP.NET MVC (二)——ASP.NET MVC 數(shù)據(jù)傳遞

七天學(xué)會ASP.NET MVC (三)——ASP.Net MVC 數(shù)據(jù)處理

七天學(xué)會ASP.NET MVC (四)——用戶授權(quán)認(rèn)證問題

七天學(xué)會ASP.NET MVC (五)——Layout頁面使用和用戶角色管理

七天學(xué)會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īng)用——第一部分—安裝

  • 什么是Areas?

  • 關(guān)于實(shí)驗(yàn)33

  • 實(shí)驗(yàn)34——?jiǎng)?chuàng)建單頁應(yīng)用——第二部分—顯示Employee

  • 實(shí)驗(yàn)35——?jiǎng)?chuàng)建單頁應(yīng)用——第三部分—新建Employee

  • 實(shí)驗(yàn)36——?jiǎng)?chuàng)建單頁應(yīng)用——第三部分—上傳

 

實(shí)驗(yàn)32 ———整理項(xiàng)目組織結(jié)構(gòu)

實(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”

七天學(xué)會ASP.NET MVC(七)——?jiǎng)?chuàng)建單頁應(yīng)用

 

重復(fù)上述步驟 ,創(chuàng)建文件夾“Model”,“ViewModel”,”Data Access Layer”

七天學(xué)會ASP.NET MVC(七)——?jiǎng)?chuàng)建單頁應(yīng)用

2. 創(chuàng)建數(shù)據(jù)訪問層工程

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

3. 創(chuàng)建業(yè)務(wù)層和業(yè)務(wù)實(shí)體項(xiàng)

在Model文件夾下創(chuàng)建新類庫“BusinessLayer”和“BusinessEntities”

4. 創(chuàng)建ViewModel 項(xiàng)

在ViewModel 文件夾下新建類庫項(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 類庫中。

七天學(xué)會ASP.NET MVC(七)——?jiǎng)?chuàng)建單頁應(yīng)用

 

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 類庫項(xiàng)中。

7. 刪除ViewModels文件夾

8. 將整個(gè)MVC項(xiàng)目剪切到”View And Controller”解決方案文件夾中。

 

7. Build

選擇Build->Build Solution from menu bar,會報(bào)錯(cuò)。

七天學(xué)會ASP.NET MVC(七)——?jiǎng)?chuàng)建單頁應(yīng)用

8. 改錯(cuò)

1. 給ViewModel項(xiàng)添加System.Web 引用

2. 在DataAccessLayer 和 BusinessLayer中使用Nuget 管理,并安裝EF(Entity Framework)(如果對于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庫,協(xié)助完成。

3. 刪除MVC 項(xiàng)目中的EF

  • 右擊MVC 項(xiàng)目,選擇”Manage Nuget packages“選項(xiàng)

  • 在彈出的對話框中選擇”Installed Packages“

  • 則會顯示所有的已安裝項(xiàng),選擇EF,點(diǎn)解卸載。

9. 編譯會發(fā)現(xiàn)還是會報(bào)錯(cuò)

七天學(xué)會ASP.NET MVC(七)——?jiǎng)?chuàng)建單頁應(yīng)用

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<SalesERPDAL>());<saleserpdal>
  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語句 和 Database.SetInitializer 語句。 調(diào)用 BusinessSettings.SetBusiness 函數(shù):

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

再次編譯程序,會發(fā)現(xiàn)成功。

關(guān)于實(shí)驗(yàn)32

什么是解決方案文件夾?

解決方案文件夾是邏輯性的文件夾,并不是在物理磁盤上實(shí)際創(chuàng)建,這里使用解決方案文件夾就是為了使項(xiàng)目更系統(tǒng)化更有結(jié)構(gòu)。

實(shí)驗(yàn)33——?jiǎng)?chuàng)建單頁應(yīng)用 1—安裝

實(shí)驗(yàn)33中,不再使用已創(chuàng)建好的控制器和視圖,會創(chuàng)建新的控制器及視圖,創(chuàng)建新控制器和視圖原因如下:

1. 保證現(xiàn)有的選項(xiàng)完整,也會用于舊版本與新版本對比 
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,在彈出對話框中輸入SPA,點(diǎn)擊確認(rèn),生成新的文件夾,因?yàn)樵谠撐募A中不需要Model中Area的文件夾,刪掉。

七天學(xué)會ASP.NET MVC(七)——?jiǎng)?chuàng)建單頁應(yīng)用

七天學(xué)會ASP.NET MVC(七)——?jiǎng)?chuàng)建單頁應(yīng)用

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

Areas

Areas是實(shí)現(xiàn)Asp.net MVC 項(xiàng)目模塊化管理的一種簡單方法。

每個(gè)項(xiàng)目由多個(gè)模塊組成,如支付模塊,客戶關(guān)系模塊等。在傳統(tǒng)的項(xiàng)目中,采用“文件夾”來實(shí)現(xiàn)模塊化管理的,你會發(fā)現(xiàn)在單個(gè)項(xiàng)目中會有多個(gè)同級文件夾,每個(gè)文件夾代表一個(gè)模塊,并保存各模塊相關(guān)的文件。

然而,在Asp.net MVC 項(xiàng)目中使用自定義文件夾實(shí)現(xiàn)功能模塊化會導(dǎo)致很多問題。

下面是在Asp.Net MVC中使用文件夾來實(shí)現(xiàn)模塊化功能需要注意的幾點(diǎn):

  • DataAccessLayer, BusinessLayer, BusinessEntities和ViewModels的使用不會導(dǎo)致其他問題,在任何情況下,可視作簡單的類使用。

  • Controllers—只能保存在Controller 文件夾,但是這不是大問題,從MVC4開始,控制器的路徑不再受限?,F(xiàn)在可以放在任何文件目錄下。

  • 所有的Views必須放在“~/Views/ControllerName” or “~/Views/Shared”文件夾。

 

2. 創(chuàng)建必要的ViewModels

在ViewModel類庫下新建文件夾并命名為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這種形式。

如果不定義別名的話,會產(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:  <!DOCTYPE html>
   4:
   5:  <html>
   6:  <head>
   7:      <meta name="viewport" content="width=device-width" />
   8:      <title>Employee Single Page Application</title>

5. 運(yùn)行測試

七天學(xué)會ASP.NET MVC(七)——?jiǎng)?chuàng)建單頁應(yīng)用

關(guān)于實(shí)驗(yàn)33

為什么在控制器名前需要使用SPA關(guān)鍵字?

在ASP.NET MVC應(yīng)用中添加area時(shí),Visual Studio會自動(dòng)創(chuàng)建并命名為“[AreaName]AreaRegistration.cs”的文件,其中包含了AreaRegistration的派生類。該類定義了 AreaName屬性和用來定義register路勁信息的 RegisterArea 方法。

在本次實(shí)驗(yàn)中你會發(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,我們會在Controllers前面加SPA關(guān)鍵字。

 

SPAAreaRegistrationRegisterArea方法是怎樣被調(diào)用的?

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

   1:  AreaRegistration.RegisterAllAreas();

RegisterAllAreas方法會找到應(yīng)用程序域中所有AreaRegistration的派生類,并主動(dòng)調(diào)用RegisterArea方法

是否可以不使用SPA關(guān)鍵字來調(diào)用MainController?

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

實(shí)驗(yàn)34——?jiǎng)?chuàng)建單頁應(yīng)用2—顯示Employees

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 List<employeeviewmodel> Employees { get; set; }
   6:      }
   7:  }
   8:  </employeeviewmodel>

注意:這兩個(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:      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. 創(chuàng)建AddNewLink 分部View

之前添加AddNewLink 分部View已經(jīng)無法使用,因?yàn)锳nchor標(biāo)簽會造成全局刷新,我們的目標(biāo)是創(chuàng)建”單頁應(yīng)用“,因此不需要全局刷新。

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

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

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:  <div>
   4:      @{
   5:          Html.RenderAction("GetAddNewLink");
   6:      }
   7:
   8:      <table border="1" id="EmployeeTable">
   9:          <tr>
  10:              <th>Employee Name</th>

6. 設(shè)置EmployeeList 為初始頁面

打開“~/Areas/Spa/Views/Main/Index.cshtml”文件,在Div標(biāo)簽內(nèi)包含EmployeeList action結(jié)果。

   1:  ...
   2:  </div>

7. 運(yùn)行

七天學(xué)會ASP.NET MVC(七)——?jiǎng)?chuàng)建單頁應(yīng)用

實(shí)驗(yàn) 35——?jiǎng)?chuàng)建單頁應(yīng)用3—?jiǎng)?chuàng)建Employee

1. 創(chuàng)建AddNew ViewModels

在SPA中新建 ViewModel類庫項(xiàng)的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. 創(chuàng)建AddNew action 方法

在MainController中輸入using 語句:

   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.SPA
   2:  @model CreateEmployeeViewModel
   3:  <div>
   4:      <table>
   5:          <tr>
   6:              <td>
   7:                  First Name:
   8:              </td>

4. 添加 jQuery UI

右擊項(xiàng)目選擇“Manage Nuget Manager”。找到“jQuery UI”并安裝。

七天學(xué)會ASP.NET MVC(七)——?jiǎng)?chuàng)建單頁應(yīng)用

項(xiàng)目中會自動(dòng)添加.js和.css文件

七天學(xué)會ASP.NET MVC(七)——?jiǎng)?chuàng)建單頁應(yīng)用

5. 在項(xiàng)目中添加jQuery UI

打開“~/Areas/Spa/Views/Main/Index.cshtml”,添加jQuery.js,jQueryUI.js 及所有的.css文件的引用。這些文件會通過Nuget Manager添加到j(luò)Query 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. 實(shí)現(xiàn) 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. 運(yùn)行

完成登錄步驟后導(dǎo)航到Index中,點(diǎn)擊Add New 鏈接。

七天學(xué)會ASP.NET MVC(七)——?jiǎng)?chuàng)建單頁應(yīng)用

8. 創(chuàng)建 ResetForm 方法

在CreateEmployee.cshtml頂部,輸入以下代碼,創(chuàng)建ResetForm函數(shù):

   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. 創(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)證

  • 會將合法值傳到服務(wù)器

  • 新Employee記錄必須保存到數(shù)據(jù)庫中

  • CreateEmployee對話框使用完成之后必須關(guān)閉

  • 插入新值后,需要更新表格。

為了實(shí)現(xiàn)三大功能,先確定一些實(shí)現(xiàn)計(jì)劃:

1.驗(yàn)證

驗(yàn)證功能可以使用之前項(xiàng)目的驗(yàn)證代碼。

2.保存功能

我們會創(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)在由于使用這兩種功能會導(dǎo)致全局刷新,因此我們將使用jQuery Ajax方法來替代Form標(biāo)簽和提交按鈕。

尋求解決方案

1. 理解問題

大家會疑惑JavaScript和Asp.NET 是兩種技術(shù),如何進(jìn)行數(shù)據(jù)交互?

解決方案: 通用數(shù)據(jù)類型

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

通用的解決方案就是將所有數(shù)據(jù)轉(zhuǎn)換為字符串類型,因?yàn)闊o論哪種技術(shù)都支持且能理解字符串類型的數(shù)據(jù)。

七天學(xué)會ASP.NET MVC(七)——?jiǎng)?chuàng)建單頁應(yīng)用

 

問題:復(fù)雜數(shù)據(jù)該怎么傳遞?

.net中的復(fù)雜數(shù)據(jù)通常指的是類和對象,這一類數(shù)據(jù),.net與其他技術(shù)傳遞復(fù)雜數(shù)據(jù)就意味著傳類對象的數(shù)據(jù),從JavaScript給其他技術(shù)傳的復(fù)雜類型數(shù)據(jù)就是JavaScript對象。因此是不可能直接傳遞的,因此我們需要將對象類型的數(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ù)都會考慮的一種標(biāo)準(zhǔn)格式。

如下,用C#創(chuàng)建的Employee對象,可以用XML 表示為:

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

因此可選的解決方案就是,將技術(shù)1中的復(fù)雜數(shù)據(jù)轉(zhuǎn)換為XML格式的字符串,然再發(fā)送給技術(shù)2.

七天學(xué)會ASP.NET MVC(七)——?jiǎng)?chuàng)建單頁應(yīng)用

然而使用XML格式可能會導(dǎo)致數(shù)據(jù)占用的字節(jié)數(shù)太多,不易發(fā)送。數(shù)據(jù)SiZE越大意味著性能越低效。還有就是XML的創(chuàng)建和解析比較困難。

為了處理XML創(chuàng)建和解析的問題,使用JSON格式,全稱“JavaScript Object Notation”。

C#創(chuàng)建的Employee對象用JSON表示:

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

JSON數(shù)據(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:  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. 創(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 = $('<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. 運(yùn)行

七天學(xué)會ASP.NET MVC(七)——?jiǎng)?chuàng)建單頁應(yīng)用

關(guān)于實(shí)驗(yàn)35

JSON 方法的作用是什么?

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

七天學(xué)會ASP.NET MVC(七)——?jiǎng)?chuàng)建單頁應(yīng)用

ExecuteResult是ActionResult中聲明的抽象方法,ActionResult所有的子類都定義了該方法。在第一篇博客中我們已經(jīng)講過ViewResult 的ExecuteResult方法實(shí)現(xiàn)的功能,有什么不理解的可以翻看第一篇博客。

實(shí)驗(yàn)36——?jiǎng)?chuàng)建單頁應(yīng)用—4—批量上傳

1. 創(chuàng)建SpaBulkUploadController

創(chuàng)建新的AsyncController“ SpaBulkUploadController”

   1:  namespace WebApplication1.Areas.SPA.Controllers
   2:  {
   3:      public class SpaBulkUploadController : AsyncController
   4:      {
   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:  <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. 創(chuàng)建 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 >

5. 運(yùn)行

七天學(xué)會ASP.NET MVC(七)——?jiǎng)?chuàng)建單頁應(yīng)用

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. 創(chuàng)建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. 創(chuàng)建Upload 函數(shù)

打開”~/Areas/Spa/Views/SpaBulkUpload”的Index View。創(chuàng)建JavaScript函數(shù),命名為“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. 運(yùn)行

七天學(xué)會ASP.NET MVC(七)——?jiǎng)?chuàng)建單頁應(yīng)用

七天學(xué)會ASP.NET MVC(七)——?jiǎng)?chuàng)建單頁應(yīng)用

總結(jié)

七天學(xué)會MVC 就到這里結(jié)束了,謝謝大家的支持,希望大家都能夠掌握所講述的MVC知識,希望都能夠進(jìn)步!

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


向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI