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
本章内容:Ajax 提交自定义对象、Ajax 提交数组
此处全部都在 /AdminAccount/Index 页面完成。
一、学生信息编辑首页
创建一个 Admin 控制器用于编辑学生信息:
1 [Authorize(Roles = "Admin")] 2 public class AdminAccountController : Controller 3 { 4 private UserManager<Student> _userManager; 5 6 public AdminAccountController(UserManager<Student> userManager) 7 { 8 _userManager = userManager; 9 } 10 11 public IActionResult Index() 12 { 13 ICollection<Student> students = _userManager.Users.ToList(); 14 return View(students); 15 } 16 }
视图:
1 @using LibraryDemo.Models.DomainModels 2 @model IEnumerable<LibraryDemo.Models.DomainModels.Student> 3 @{ 4 ViewData["Title"] = "AccountInfo"; 5 Student stu = new Student(); 6 } 7 <link rel="stylesheet" href="~/css/BookInfo.css" /> 8 9 <h2>学生信息</h2> 10 11 <div id="buttonGroup"> 12 <button class="btn btn-primary" onclick="return addStudent()">添加学生</button> 13 <button class="btn btn-danger" onclick="return confirmDelete()">删除学生</button> 14 </div> 15 16 17 <br /> 18 <table> 19 <thead> 20 <tr> 21 <th></th> 22 <th>@Html.LabelFor(m => stu.UserName)</th> 23 <th>@Html.LabelFor(m => stu.Name)</th> 24 <th>@Html.LabelFor(m => stu.Degree)</th> 25 <th>@Html.LabelFor(m => stu.PhoneNumber)</th> 26 <th>@Html.LabelFor(m => stu.Email)</th> 27 <th>@Html.LabelFor(m => stu.MaxBooksNumber)</th> 28 </tr> 29 </thead> 30 <tbody id="studentList"> 31 32 @if (!@Model.Any()) 33 { 34 <tr><td colspan="6">未有学生信息</td></tr> 35 } 36 else 37 { 38 foreach (var student in Model) 39 { 40 <tr> 41 <td><input type="checkbox" name="userNames" value="@student.UserName" /></td> 42 <td>@student.UserName</td> 43 <td>@student.Name</td> 44 <td>@Html.DisplayFor(m => student.Degree)</td> 45 <td>@student.PhoneNumber</td> 46 <td>@student.Email</td> 47 <td>@student.MaxBooksNumber</td> 48 </tr> 49 } 50 } 51 </tbody> 52 </table>
结果:
二、增加新学生
此处打算使用 Ajax 来实现无刷新页面更新,因此动作方法返回类型为 Json 。
动作方法:
此处需注意在参数处添加 [FromBody] 修饰,否则无法读取来自页面的数据。
为节省带宽,此处仅返回添加的学生的 JSON 。
1 [HttpPost] 2 public async Task<JsonResult> AddStudent([FromBody]Student student) 3 { 4 if (_userManager.CreateAsync(student,"123456").Result.Succeeded) 5 { 6 return await AddedStudent(student.UserName); 7 } 8 9 return Json("Failed"); 10 } 11 12 public async Task<JsonResult> AddedStudent(string userName) 13 { 14 Student student=await _userManager.Users.FirstOrDefaultAsync(s => s.UserName == userName); 15 return Json(new 16 { 17 userName = student.UserName, 18 name = student.Name, 19 degree = student.Degree == Degrees.CollegeStudent ? "本科生" : (student.Degree == Degrees.Postgraduate ? "研究生" : "博士生"), 20 phoneNumber = student.PhoneNumber, 21 email = student.Email, 22 maxBooksNumber = student.MaxBooksNumber 23 }); 24 }
在视图中添加 JS 代码:
此处 JS 代码先是点击 添加书籍 按钮插入一行用于编辑的区域,然后通过插入区域的提交按钮提交信息,在信息成功返回后删除原来进行编辑的行,通过返回的信息添加新的行。
27-33 中由于 ASP.NET Core 后台返回 JSON 数据时会对数据的键的首字母进行小写处理,因此此处读取属性也是使用首字母小写,在后台的键也是使用首字母小写加以强调。
1 <script> 2 function postAddStudent() { 3 $.ajax({ 4 url: "@Url.Action("AddStudent")", 5 contentType: "application/json", 6 method: "POST", 7 data: JSON.stringify({ 8 UserName: $("#UserName").val(), 9 Name: $("#Name").val(), 10 Degree:$("#Degree").val(), 11 PhoneNumber: $("#PhoneNumber").val(), 12 Email: $("#Email").val(), 13 MaxBooksNumber: $("#MaxBooksNumber").val() 14 }), 15 success: function (student) { 16 addStudentToTable(student); 17 } 18 }); 19 } 20 21 function addStudentToTable(student) { 22 var studentList = document.getElementById("studentList"); 23 var studentInfo = document.getElementById("studentInfo"); 24 studentList.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] 2 public async Task<JsonResult> RemoveStudent([FromBody]IEnumerable<string> userNames) 3 { 4 Student removedStudent; 5 foreach (var userName in userNames) 6 { 7 removedStudent =await _userManager.FindByNameAsync(userName); 8 if (removedStudent!=null) 9 { 10 await _userManager.DeleteAsync(removedStudent); 11 } 12 } 13 return GetStudentData(); 14 } 15 16 public JsonResult GetStudentData() 17 { 18 var students = _userManager.Users.Select(s =>new 19 { 20 userName=s.UserName, 21 name=s.Name, 22 degree=s.Degree==Degrees.CollegeStudent?"本科生":(s.Degree==Degrees.Postgraduate?"研究生":"博士生"), 23 phoneNumber = s.PhoneNumber, 24 email = s.Email, 25 maxBooksNumber = s.MaxBooksNumber 26 }); 27 return Json(students); 28 }
视图添加 JS 函数:
18 行为数组元素的提交方式,不需像之前一样—— {values:values},否则无法进行数据绑定而导致后台接收到空数据。
为了对表格进行更新,先是通过 jQuery 获取了 tbody 的部分,清空后添加来自后台的新信息:
1 <script> 2 function confirmDelete() { 3 var userNames = document.getElementsByName("userNames"); 4 var message = "确认删除"; 5 var values = []; 6 for (i in userNames) { 7 if (userNames[i].checked) { 8 message = message + userNames[i].value+","; 9 values.push(userNames[i].value); 10 } 11 } 12 message = message + "?"; 13 if (confirm(message)) { 14 $.ajax({ 15 url: "@Url.Action("RemoveStudent")", 16 contentType: "application/json", 17 method: "POST", 18 data: JSON.stringify(values), 19 success: function(students) { 20 updateTable(students); 21 } 22 }); 23 } 24 } 25 26 function updateTable(data) { 27 var body = $("#studentList"); 28 body.empty(); 29 for (var i = 0; i < data.length; i++) { 30 var person = data[i]; 31 body.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>
结果: