- ASP.NET Core 教程
- ASP.NET Core - 首页
- ASP.NET Core - 概述
- ASP.NET Core - 环境设置
- ASP.NET Core - 新建项目
- ASP.NET Core - 项目布局
- ASP.NET Core - Project.Json
- ASP.NET Core - 配置
- ASP.NET Core - 中间件
- ASP.NET Core - 异常
- ASP.NET Core - 静态文件
- ASP.NET Core - 设置 MVC
- ASP.NET Core - MVC 设计模式
- ASP.NET Core - 路由
- ASP.NET Core - 属性路由
- ASP.NET Core - 操作结果
- ASP.NET Core - 视图
- 设置 Entity Framework
- ASP.NET Core - DBContext
- ASP.NET Core - Razor 布局视图
- ASP.NET Core - Razor 视图启动
- ASP.NET Core - Razor 视图导入
- ASP.NET Core - Razor 标签助手
- ASP.NET Core - Razor 编辑表单
- ASP.NET Core - 身份概述
- ASP.NET Core - 授权属性
- 身份配置
- ASP.NET Core - 身份迁移
- ASP.NET Core - 用户注册
- ASP.NET Core - 创建用户
- ASP.NET Core - 登录和注销
- ASP.NET Core 有用资源
- ASP.NET Core - 快速指南
- ASP.NET Core - 有用资源
- ASP.NET Core - 讨论
ASP.NET Core - Razor 编辑表单
在本章中,我们将继续讨论标签助手。我们还将在应用程序中添加一个新功能,并使其能够编辑现有员工的详细信息。我们将首先在每个员工旁边添加一个链接,该链接将转到 HomeController 上的 Edit 操作。
@model HomePageViewModel
@{
ViewBag.Title = "Home";
}
<h1>Welcome!</h1>
<table>
@foreach (var employee in Model.Employees) {
<tr>
<td>@employee.Name</td>
<td>
<a asp-controller = "Home" asp-action = "Details"
asp-routeid = "@employee.Id">Details</a>
<a asp-controller = "Home" asp-action = "Edit"
asp-routeid = "@employee.Id">Edit</a>
</td>
</tr>
}
</table>
我们还没有 Edit 操作,但我们需要一个可以编辑的员工 ID。因此,让我们首先通过右键单击 **Views → Home** 文件夹并选择 **添加 → 新建项** 来创建一个新的视图。
在中间窗格中,选择 MVC 视图页面;将页面命名为 Edit.cshtml。现在,单击“添加”按钮。
在 **Edit.cshtml** 文件中添加以下代码。
@model Employee
@{
ViewBag.Title = $"Edit {Model.Name}";
}
<h1>Edit @Model.Name</h1>
<form asp-action="Edit" method="post">
<div>
<label asp-for = "Name"></label>
<input asp-for = "Name" />
<span asp-validation-for = "Name"></span>
</div>
<div>
<input type = "submit" value = "Save" />
</div>
</form>
对于此页面的标题,我们可以说我们想要编辑,然后提供员工姓名。
Edit 前面的美元符号将允许运行时用该属性中的值(如员工姓名)替换 Model.Name。
在表单标签内,我们可以使用像 asp-action 和 asp-controller 这样的标签助手。这样,当用户提交此表单时,它将直接转到特定的控制器操作。
在这种情况下,我们希望转到同一控制器的 Edit 操作,并且我们希望明确说明此表单上的方法应该使用 HttpPost。
表单的默认方法是 GET,我们不希望使用 GET 操作来编辑员工。
在标签标签中,我们使用了 asp-for 标签助手,它表示这是模型 Name 属性的标签。此标签助手可以设置 Html.For 属性以具有正确的值,并设置此标签的内部文本,以便它实际显示我们想要的内容,例如员工姓名。
让我们转到 HomeController 类并添加 **Edit** 操作,该操作返回一个视图,该视图为用户提供一个编辑员工的表单,然后我们将需要第二个 Edit 操作来响应 HttpPost,如下所示。
[HttpGet]
public IActionResult Edit(int id) {
var context = new FirstAppDemoDbContext();
SQLEmployeeData sqlData = new SQLEmployeeData(context);
var model = sqlData.Get(id);
if (model == null) {
return RedirectToAction("Index");
}
return View(model);
}
首先,我们需要一个响应 GET 请求的 edit 操作。它将获取员工 ID。此处的代码将类似于我们在 Details 操作中拥有的代码。我们将首先提取用户想要编辑的员工的数据。我们还需要确保员工确实存在。如果不存在,我们将把用户重定向回 Index 视图。但当员工存在时,我们将呈现 Edit 视图。
我们还需要响应表单将发送的 HttpPost。
让我们在 HomeController.cs 文件中添加一个新类,如下面的程序所示。
public class EmployeeEditViewModel {
[Required, MaxLength(80)]
public string Name { get; set; }
}
在将响应 HttpPost 的 Edit 操作中,将使用 EmployeeEditViewModel,而不是员工本身,因为我们只想捕获 Edit.cshtml 文件中表单中的项目。
以下是 Edit 操作的实现。
[HttpPost]
public IActionResult Edit(int id, EmployeeEditViewModel input) {
var context = new FirstAppDemoDbContext();
SQLEmployeeData sqlData = new SQLEmployeeData(context);
var employee = sqlData.Get(id);
if (employee != null && ModelState.IsValid) {
employee.Name = input.Name;
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 是否有效,并确保此员工在数据库中并且在对数据库执行更新操作之前不为空。
如果上述条件都不成立,我们将返回一个视图并允许用户重试。尽管在具有并发用户的实际应用程序中,如果员工为空,则可能是因为员工详细信息被其他人删除了。
如果该员工不存在,请告诉用户该员工不存在。
否则,检查 ModelState。如果 ModelState 无效,则返回一个视图。这允许修复编辑并使 ModelState 有效。
将名称从 Input 视图模型复制到从数据库检索到的员工,并保存更改。SaveChagnes() 方法将把所有这些更改刷新到数据库。
以下是 HomeController 的完整实现。
using Microsoft.AspNet.Mvc;
using FirstAppDemo.ViewModels;
using FirstAppDemo.Services;
using FirstAppDemo.Entities;
using FirstAppDemo.Models;
using System.Collections.Generic;
using System.Linq;
using System.ComponentModel.DataAnnotations;
namespace FirstAppDemo.Controllers {
public class HomeController : Controller {
public ViewResult Index() {
var model = new HomePageViewModel();
using (var context = new FirstAppDemoDbContext()) {
SQLEmployeeData sqlData = new SQLEmployeeData(context);
model.Employees = sqlData.GetAll();
}
return View(model);
}
public IActionResult Details(int id) {
var context = new FirstAppDemoDbContext();
SQLEmployeeData sqlData = new SQLEmployeeData(context);
var model = sqlData.Get(id)
if (model == null) {
return RedirectToAction("Index");
}
return View(model);
}
[HttpGet]
public IActionResult Edit(int id) {
var context = new FirstAppDemoDbContext();
SQLEmployeeData sqlData = new SQLEmployeeData(context);
var model = sqlData.Get(id);
if (model == null) {
return RedirectToAction("Index");
}
return View(model);
}
[HttpPost]
public IActionResult Edit(int id, EmployeeEditViewModel input) {
var context = new FirstAppDemoDbContext();
SQLEmployeeData sqlData = new SQLEmployeeData(context);
var employee = sqlData.Get(id);
if (employee != null && ModelState.IsValid) {
employee.Name = input.Name;
context.SaveChanges();
return RedirectToAction("Details", new { id = employee.Id });
}
return View(employee);
}
}
public class SQLEmployeeData {
private FirstAppDemoDbContext _context { get; set; }
public SQLEmployeeData(FirstAppDemoDbContext context) {
_context = context;
}
public void Add(Employee emp) {
_context.Add(emp);
_context.SaveChanges();
}
public Employee Get(int ID) {
return _context.Employees.FirstOrDefault(e => e.Id == ID);
}
public IEnumerable<Employee> GetAll() {
return _context.Employees.ToList<Employee>();
}
}
public class HomePageViewModel {
public IEnumerable<Employee> Employees { get; set; }
}
public class EmployeeEditViewModel {
[Required, MaxLength(80)]
public string Name { get; set; }
}
}
让我们编译程序并运行应用程序。
我们现在有一个可用的“编辑”链接;让我们通过单击“编辑”链接来编辑 Josh 的详细信息。
让我们将姓名更改为 Josh Groban。
单击“保存”按钮。
您可以看到名称已更改为 Josh Groban,如上面的屏幕截图所示。现在让我们单击“主页”链接。
在主页上,您现在将看到更新后的名称。