ASP.NET Core 打造一個簡單的圖書館管理系統(九) 學生資訊增刪(終章)
前言:
本系列文章主要為我之前所學知識的一次微小的實踐,以我學校圖書館管理系統為雛形所作。
本系列文章主要參考資料:
微軟文件:https://docs.microsoft.com/zh-cn/aspnet/core/getting-started/?view=aspnetcore-2.1&tabs=windows
《Pro ASP.NET MVC 5》、《鋒利的 jQuery》
當此系列文章寫完後會在一週內推出修正版。
此係列皆使用 VS2017+C# 作為開發環境。如果有什麼問題或者意見歡迎在留言區進行留言。
專案 github 地址: https://github.com/NanaseRuri/LibraryDemo
修改前地址: https://github.com/NanaseRuri/LibraryDemo/tree/SomeError
本章內容:Ajax 提交自定義物件、Ajax 提交陣列
此處全部都在 /AdminAccount/Index 頁面完成。
一、學生資訊編輯首頁
建立一個 Admin 控制器用於編輯學生資訊:
1[Authorize(Roles = "Admin")] 2public class AdminAccountController : Controller 3{ 4private UserManager<Student> _userManager; 5 6public AdminAccountController(UserManager<Student> userManager) 7{ 8_userManager = userManager; 9} 10 11public IActionResult Index() 12{ 13ICollection<Student> students = _userManager.Users.ToList(); 14return View(students); 15} 16}
@using LibraryDemo.Models.DomainModels @model IEnumerable<LibraryDemo.Models.DomainModels.Student> @{ ViewData["Title"] = "AccountInfo"; Student stu = new Student(); } <link rel="stylesheet" href="~/css/BookInfo.css" /> <h2>學生資訊</h2> <div id="buttonGroup"> <button class="btn btn-primary" onclick="return addStudent()">新增學生</button> <button class="btn btn-danger" onclick="return confirmDelete()">刪除學生</button> </div> <br /> <table> <thead> <tr> <th></th> <th>@Html.LabelFor(m => stu.UserName)</th> <th>@Html.LabelFor(m => stu.Name)</th> <th>@Html.LabelFor(m => stu.Degree)</th> <th>@Html.LabelFor(m => stu.PhoneNumber)</th> <th>@Html.LabelFor(m => stu.Email)</th> <th>@Html.LabelFor(m => stu.MaxBooksNumber)</th> </tr> </thead> <tbody id="studentList"> @if ([email protected]()) { <tr><td colspan="6">未有學生資訊</td></tr> } else { foreach (var student in Model) { <tr> <td><input type="checkbox" name="userNames" value="@student.UserName" /></td> <td>@student.UserName</td> <td>@student.Name</td> <td>@Html.DisplayFor(m => student.Degree)</td> <td>@student.PhoneNumber</td> <td>@student.Email</td> <td>@student.MaxBooksNumber</td> </tr> } } </tbody> </table>
結果:
二、增加新學生
此處打算使用 Ajax 來實現無重新整理頁面更新,因此動作方法返回型別為 Json 。
動作方法:
此處需注意在引數處新增 [FromBody] 修飾,否則無法讀取來自頁面的資料。
為節省頻寬,此處僅返回新增的學生的 JSON 。
1[HttpPost] 2public async Task<JsonResult> AddStudent([FromBody]Student student) 3{ 4if (_userManager.CreateAsync(student,"123456").Result.Succeeded) 5{ 6return await AddedStudent(student.UserName); 7} 8 9return Json("Failed"); 10} 11 12public async Task<JsonResult> AddedStudent(string userName) 13{ 14Student student=await _userManager.Users.FirstOrDefaultAsync(s => s.UserName == userName); 15return Json(new 16{ 17userName = student.UserName, 18name = student.Name, 19degree = student.Degree == Degrees.CollegeStudent ? "本科生" : (student.Degree == Degrees.Postgraduate ? "研究生" : "博士生"), 20phoneNumber = student.PhoneNumber, 21email = student.Email, 22maxBooksNumber = student.MaxBooksNumber 23}); 24}
在檢視中新增 JS 程式碼:
此處 JS 程式碼先是點選 新增書籍 按鈕插入一行用於編輯的區域,然後通過插入區域的提交按鈕提交資訊,在資訊成功返回後刪除原來進行編輯的行,通過返回的資訊新增新的行。
27-33 中由於 ASP.NET Core 後臺返回 JSON 資料時會對資料的鍵的首字母進行小寫處理,因此此處讀取屬性也是使用首字母小寫,在後臺的鍵也是使用首字母小寫加以強調。
1 <script> 2function postAddStudent() { 3$.ajax({ 4url: "@Url.Action("AddStudent")", 5contentType: "application/json", 6method: "POST", 7data: JSON.stringify({ 8UserName: $("#UserName").val(), 9Name: $("#Name").val(), 10Degree:$("#Degree").val(), 11PhoneNumber: $("#PhoneNumber").val(), 12Email: $("#Email").val(), 13MaxBooksNumber: $("#MaxBooksNumber").val() 14}), 15success: function (student) { 16addStudentToTable(student); 17} 18}); 19} 20 21function addStudentToTable(student) { 22var studentList = document.getElementById("studentList"); 23var studentInfo = document.getElementById("studentInfo"); 24studentList.removeChild(studentInfo); 25 26$("#studentList").append(`<tr>` + 27`<td><input type="checkbox" name="userNames" value="${student.userName}" /></td>` + 28`<td>${student.userName}</td>` + 29`<td>${student.name}</td>`+ 30`<td>${student.degree}</td>` + 31`<td>${student.phoneNumber}</td>` + 32`<td>${student.email}</td>` + 33`<td>${student.maxBooksNumber}</td >` + 34`</tr>`); 35} 36 </script>
結果:
三、 批量移除學生
此處亦可以只返回更新過的元素,但為了演示 ASP.NET Core 使用 Ajax 對陣列進行處理,故返回新的 Student 列表:
1[HttpPost] 2public async Task<JsonResult> RemoveStudent([FromBody]IEnumerable<string> userNames) 3{ 4Student removedStudent; 5foreach (var userName in userNames) 6{ 7removedStudent =await _userManager.FindByNameAsync(userName); 8if (removedStudent!=null) 9{ 10await _userManager.DeleteAsync(removedStudent); 11} 12} 13return GetStudentData(); 14} 15 16public JsonResult GetStudentData() 17{ 18var students = _userManager.Users.Select(s =>new 19{ 20userName=s.UserName, 21name=s.Name, 22degree=s.Degree==Degrees.CollegeStudent?"本科生":(s.Degree==Degrees.Postgraduate?"研究生":"博士生"), 23phoneNumber = s.PhoneNumber, 24email = s.Email, 25maxBooksNumber = s.MaxBooksNumber 26}); 27return Json(students); 28}
檢視新增 JS 函式:
18 行為陣列元素的提交方式,不需像之前一樣—— {values:values},否則無法進行資料繫結而導致後臺接收到空資料。
為了對錶格進行更新,先是通過 jQuery 獲取了 tbody 的部分,清空後新增來自後臺的新資訊:
1 <script> 2function confirmDelete() { 3var userNames = document.getElementsByName("userNames"); 4var message = "確認刪除"; 5var values = []; 6for (i in userNames) { 7if (userNames[i].checked) { 8message = message + userNames[i].value+","; 9values.push(userNames[i].value); 10} 11} 12message = message + "?"; 13if (confirm(message)) { 14$.ajax({ 15url: "@Url.Action("RemoveStudent")", 16contentType: "application/json", 17method: "POST", 18data: JSON.stringify(values), 19success: function(students) { 20updateTable(students); 21} 22}); 23} 24} 25 26function updateTable(data) { 27var body = $("#studentList"); 28body.empty(); 29for (var i = 0; i < data.length; i++) { 30var person = data[i]; 31body.append(`<tr><td><input type="checkbox" name="userNames" value="${person.userName}" /></td> 32<td>${person.userName}</td><td>${person.name}</td><td>${person.degree}</td> 33<td>${person.phoneNumber}</td><td>${person.email}</td><td>${person.maxBooksNumber}</td></tr>`); 34} 35}; 36 </script>
結果: