ASP.NET Core Razor 编辑表单

在本章中,我们将继续讨论标签助手。我们还将在应用程序中添加一个新功能,使其能够编辑现有员工的详细信息。我们将首先在每个员工的侧面添加一个链接,该链接将转到 HomeController 上的编辑操作。

  1. @model HomePageViewModel
  2. @{
  3. ViewBag.Title = "Home";
  4. }
  5. <h1>Welcome!</h1>
  6. <table>
  7. @foreach (var employee in Model.Employee)
  8. {
  9. <tr>
  10. <td>@employee.EmployeeName</td>
  11. <td>
  12. <a asp-controller="Home" asp-action="Details"
  13. asp-route-id="@employee.ID">Details</a>
  14. <a asp-controller="Home" asp-action="Edit"
  15. asp-route-id="@employee.ID">Edit</a>
  16. </td>
  17. </tr>
  18. }
  19. </table>

我们还没有 编辑 操作,但我们需要一个可以编辑的员工 ID。因此,让我们首先通过右键单击 Views →Home 目录选择 添加→新建项

然后命名为 Edit.cshtml,点击 添加 按钮。

  1. **Edit.cshtml** 的代码如下:
  2. @model MyFirstCoreWebApp.Models.Employee
  3. @{
  4. ViewBag.Title = $"Edit {Model.EmployeeName}";
  5. }
  6. <h1>Edit @Model.EmployeeName</h1>
  7. <form asp-action="Edit" method="post">
  8. <div>
  9. <label>员工名称</label>
  10. <input asp-for="EmployeeName" />
  11. <span asp-validation-for="EmployeeName"></span>
  12. </div>
  13. <div>
  14. <input type="submit" value="保存" />
  15. </div>
  16. </form>

在这个页面上,我们可以编辑员工姓名。

  • Edit 前面的美元符号将可以在运行时将 Model.EmployeeName 替换为该属性中的值,如雇员名称。
  • 在表单标签中,我们可以使用标签助手,如 asp-actionasp-controller。因此,当用户提交此表单时,它将直接转到特定的控制器的 Action
  • 在这种情况下,我们希望转到同一个控制器上的 Edit 操作,并且我们希望明确表示,对于此表单上的方法,它应该使用 HttpPost
  • 表单的默认方法是 GET,而我们不想使用 GET 操作来编辑员工。
  • 在标签标签中,我们使用 asp 作为标签助手,它表示这是模型的 EmployeeName 属性的标签。此标记帮助器可以设置 Html.For 属性,使其具有正确的值,并设置此标签的内部文本,以便它实际显示我们想要的内容,如员工姓名。

让我们转到 HomeController 类并添加 Edit 操作,该操作返回给用户一个表单以编辑员工的视图,然后我们将需要第二个 Edit 操作,它将响应 HttpPost,如下所示。

  1. [HttpGet]
  2. public IActionResult Edit(int id)
  3. {
  4. var model = _context.Employees.Find(id);
  5. if (model == null)
  6. {
  7. return RedirectToAction("Index");
  8. }
  9. return View(model);
  10. }

首先,我们需要响应 GET 请求的编辑操作。它将采用员工 ID。此处的代码将与 Detail 操作中的代码类似。我们将首先提取用户想要编辑的员工数据。我们还需要确保员工确实存在。如果它不存在,我们会将用户重定向回 Index 视图。但当员工存在时,我们将呈现 Edit 视图。

我们还需要响应表单将发送的 HttpPost

让我们在 HomeController.cs 文件中添加一个新类,如下程序所示。

  1. public class EmployeeEditViewModel {
  2. [Required, MaxLength(80)]
  3. public string EmployeeName { get; set; }
  4. }

在将响应 HttpPostEdit Action 中,将采用 EmployeeEditViewModel,而不是 Employee 本身,因为我们只想捕获 Edit.cshtml 文件中的表单项。

以下是 Edit 操作的实现。

  1. [HttpPost]
  2. public IActionResult Edit(int id, EmployeeEditViewModel input)
  3. {
  4. var employee = _context.Employees.Find(id);
  5. if (employee != null && ModelState.IsValid)
  6. {
  7. employee.EmployeeName = input.EmployeeName;
  8. _context.SaveChanges();
  9. return RedirectToAction("Details", new { id = employee.ID });
  10. }
  11. return View(employee);
  12. }

根据我们的路由规则,编辑表单应该始终从 URL 中具有 ID 的 URL 传递,例如 /home/edit/1

  • 表单总是会返回到同一个 URL,/home/edit/1
  • MVC 框架将能够从 URL 中提取该 ID 并将其作为参数传递。
  • 在我们在数据库中执行更新操作之前,我们始终需要检查 ModelState 是否有效,并确保该员工在数据库中且不为空。
  • 如果这些都不为 true,我们将返回一个视图并允许用户重试。尽管在具有并发用户的实际应用程序中,如果雇员为空,可能是因为雇员详细信息被某人删除了。
  • 如果该员工不存在,请提示用户该员工并不存在。
  • 否则,请检查 ModelState。如果 ModelState 无效,则返回视图。这可以修复编辑并使 ModelState 有效。
  • 将名称从 Input 视图模型复制到从数据库中检索到的员工,并保存更改。SaveChagnes() 方法将把所有这些更改保存到数据库中。

下面是完整的 HomeController 文件代码:

  1. using Microsoft.AspNetCore.Mvc;
  2. using MyFirstCoreWebApp.Models;
  3. using System.ComponentModel.DataAnnotations;
  4. using System.Linq;
  5. namespace MyFirstCoreWebApp.Controllers
  6. {
  7. public class HomeController : Controller
  8. {
  9. private readonly MyFirstCoreWebAppDbContext _context;
  10. public HomeController(MyFirstCoreWebAppDbContext context)
  11. {
  12. //通过构造函数注入数据库上下文
  13. _context = context;
  14. }
  15. public ViewResult Index()
  16. {
  17. HomePageViewModel employees = new HomePageViewModel();
  18. employees.Employee = _context.Employees.ToList<Employee>();
  19. return View(employees);
  20. }
  21. public IActionResult Details(int id)
  22. {
  23. var model = _context.Employees.Find(id);
  24. if (model == null)
  25. {
  26. return RedirectToAction("Index");
  27. }
  28. return View(model);
  29. }
  30. [HttpGet]
  31. public IActionResult Edit(int id)
  32. {
  33. var model = _context.Employees.Find(id);
  34. if (model == null)
  35. {
  36. return RedirectToAction("Index");
  37. }
  38. return View(model);
  39. }
  40. [HttpPost]
  41. public IActionResult Edit(int id, EmployeeEditViewModel input)
  42. {
  43. var employee = _context.Employees.Find(id);
  44. if (employee != null && ModelState.IsValid)
  45. {
  46. employee.EmployeeName = input.EmployeeName;
  47. _context.SaveChanges();
  48. return RedirectToAction("Details", new { id = employee.ID });
  49. }
  50. return View(employee);
  51. }
  52. public class EmployeeEditViewModel
  53. {
  54. [Required, MaxLength(80)]
  55. public string EmployeeName { get; set; }
  56. }
  57. }
  58. }

让我们运行程序。结果如下:

然后点击 Edit,跳转到编辑页面。如下:

让我们将名称修改为 "韩梅梅1",保存。

然后页面跳转到新的详情页面,名称已经修改为 "韩梅梅1"。

再返回首页,首页数据也已经更新。

分类导航