ASP.NET Core Razor 编辑表单
在本章中,我们将继续讨论标签助手。我们还将在应用程序中添加一个新功能,使其能够编辑现有员工的详细信息。我们将首先在每个员工的侧面添加一个链接,该链接将转到 HomeController
上的编辑操作。
@model HomePageViewModel
@{
ViewBag.Title = "Home";
}
<h1>Welcome!</h1>
<table>
@foreach (var employee in Model.Employee)
{
<tr>
<td>@employee.EmployeeName</td>
<td>
<a asp-controller="Home" asp-action="Details"
asp-route-id="@employee.ID">Details</a>
<a asp-controller="Home" asp-action="Edit"
asp-route-id="@employee.ID">Edit</a>
</td>
</tr>
}
</table>
我们还没有 编辑 操作,但我们需要一个可以编辑的员工 ID。因此,让我们首先通过右键单击 Views →Home 目录选择 添加→新建项。
然后命名为 Edit.cshtml,点击 添加 按钮。
**Edit.cshtml** 的代码如下:
@model MyFirstCoreWebApp.Models.Employee
@{
ViewBag.Title = $"Edit {Model.EmployeeName}";
}
<h1>Edit @Model.EmployeeName</h1>
<form asp-action="Edit" method="post">
<div>
<label>员工名称</label>
<input asp-for="EmployeeName" />
<span asp-validation-for="EmployeeName"></span>
</div>
<div>
<input type="submit" value="保存" />
</div>
</form>
在这个页面上,我们可以编辑员工姓名。
- Edit 前面的美元符号将可以在运行时将
Model.EmployeeName
替换为该属性中的值,如雇员名称。 - 在表单标签中,我们可以使用标签助手,如
asp-action
和asp-controller
。因此,当用户提交此表单时,它将直接转到特定的控制器的 Action。 - 在这种情况下,我们希望转到同一个控制器上的 Edit 操作,并且我们希望明确表示,对于此表单上的方法,它应该使用 HttpPost。
- 表单的默认方法是 GET,而我们不想使用 GET 操作来编辑员工。
- 在标签标签中,我们使用 asp 作为标签助手,它表示这是模型的
EmployeeName
属性的标签。此标记帮助器可以设置Html.For
属性,使其具有正确的值,并设置此标签的内部文本,以便它实际显示我们想要的内容,如员工姓名。
让我们转到 HomeController
类并添加 Edit 操作,该操作返回给用户一个表单以编辑员工的视图,然后我们将需要第二个 Edit 操作,它将响应 HttpPost,如下所示。
[HttpGet]
public IActionResult Edit(int id)
{
var model = _context.Employees.Find(id);
if (model == null)
{
return RedirectToAction("Index");
}
return View(model);
}
首先,我们需要响应 GET 请求的编辑操作。它将采用员工 ID。此处的代码将与 Detail 操作中的代码类似。我们将首先提取用户想要编辑的员工数据。我们还需要确保员工确实存在。如果它不存在,我们会将用户重定向回 Index 视图。但当员工存在时,我们将呈现 Edit 视图。
我们还需要响应表单将发送的 HttpPost。
让我们在 HomeController.cs
文件中添加一个新类,如下程序所示。
public class EmployeeEditViewModel {
[Required, MaxLength(80)]
public string EmployeeName { get; set; }
}
在将响应 HttpPost 的 Edit Action 中,将采用 EmployeeEditViewModel,而不是 Employee 本身,因为我们只想捕获 Edit.cshtml 文件中的表单项。
以下是 Edit 操作的实现。
[HttpPost]
public IActionResult Edit(int id, EmployeeEditViewModel input)
{
var employee = _context.Employees.Find(id);
if (employee != null && ModelState.IsValid)
{
employee.EmployeeName = input.EmployeeName;
_context.SaveChanges();
return RedirectToAction("Details", new { id = employee.ID });
}
return View(employee);
}
根据我们的路由规则,编辑表单应该始终从 URL 中具有 ID 的 URL 传递,例如 /home/edit/1。
- 表单总是会返回到同一个 URL,/home/edit/1。
- MVC 框架将能够从 URL 中提取该 ID 并将其作为参数传递。
- 在我们在数据库中执行更新操作之前,我们始终需要检查
ModelState
是否有效,并确保该员工在数据库中且不为空。 - 如果这些都不为 true,我们将返回一个视图并允许用户重试。尽管在具有并发用户的实际应用程序中,如果雇员为空,可能是因为雇员详细信息被某人删除了。
- 如果该员工不存在,请提示用户该员工并不存在。
- 否则,请检查
ModelState
。如果ModelState
无效,则返回视图。这可以修复编辑并使ModelState
有效。 - 将名称从 Input 视图模型复制到从数据库中检索到的员工,并保存更改。
SaveChagnes()
方法将把所有这些更改保存到数据库中。
下面是完整的 HomeController
文件代码:
using Microsoft.AspNetCore.Mvc;
using MyFirstCoreWebApp.Models;
using System.ComponentModel.DataAnnotations;
using System.Linq;
namespace MyFirstCoreWebApp.Controllers
{
public class HomeController : Controller
{
private readonly MyFirstCoreWebAppDbContext _context;
public HomeController(MyFirstCoreWebAppDbContext context)
{
//通过构造函数注入数据库上下文
_context = context;
}
public ViewResult Index()
{
HomePageViewModel employees = new HomePageViewModel();
employees.Employee = _context.Employees.ToList<Employee>();
return View(employees);
}
public IActionResult Details(int id)
{
var model = _context.Employees.Find(id);
if (model == null)
{
return RedirectToAction("Index");
}
return View(model);
}
[HttpGet]
public IActionResult Edit(int id)
{
var model = _context.Employees.Find(id);
if (model == null)
{
return RedirectToAction("Index");
}
return View(model);
}
[HttpPost]
public IActionResult Edit(int id, EmployeeEditViewModel input)
{
var employee = _context.Employees.Find(id);
if (employee != null && ModelState.IsValid)
{
employee.EmployeeName = input.EmployeeName;
_context.SaveChanges();
return RedirectToAction("Details", new { id = employee.ID });
}
return View(employee);
}
public class EmployeeEditViewModel
{
[Required, MaxLength(80)]
public string EmployeeName { get; set; }
}
}
}
让我们运行程序。结果如下:
然后点击 Edit,跳转到编辑页面。如下:
让我们将名称修改为 "韩梅梅1",保存。
然后页面跳转到新的详情页面,名称已经修改为 "韩梅梅1"。
再返回首页,首页数据也已经更新。