ASP.NET Core Razor 编辑表单 - ASP.NET Core 基础教程 - 简单教程,简单编程
原文:ASP.NET Core Razor 编辑表单 - ASP.NET Core 基础教程 - 简单教程,简单编程
ASP.NET Core Razor 编辑表单
上一章节我们介绍了标签助手和 HTML 助手,也使用标签助手和 HTML 助手分别创建了一个职工列表,感觉好像有点喜欢上标签助手和 HTML 助手了,正好之前我们只讲解了如何列出数据,没有讲解如何创建表单来添加和修改数据
要不本章节我们就来讲讲? 顺带多用用标签助手和 HTML 助手
本章中,我们将继续讨论标签助手。 与此同时,还会给 HelloWorld 应用程序中添加一项新功能,并使其能够编辑现有员工的详细信息
我们将首先在每位员工旁边上添加一个链接,以便访问 HomeController 上的 "编辑" 操作,同时将页面美化一下
修改 Index.cshtml 为如下内容
@model HomePageViewModel
@{
ViewBag.Title = "职工列表";
}
<style>
body {margin:10px auto;text-align:center}
table {
margin:0 auto;
width:90% }
table, th, td {
border:1px solid #eee;
border-collapse:collapse;
border-spacing:0;
padding:5px;
text-align:center
} .txt-left {
text-align:left;
}
</style>
<h1>职工列表</h1>
<table>
<tr>
<td>ID</td>
<td>姓名</td>
<td class="txt-left">操作</td>
</tr>
@foreach (var employee in Model.Employees)
{
<tr>
<td>@employee.ID</td>
<td>@employee.Name</td>
<td class="txt-left"><a asp-action="Detail" asp-route-Id="@employee.ID">详情</a> <a asp-controller="Home" asp-action="Edit"
asp-route-id="@employee.ID">编辑</a></td>
</tr>
}
</table>
刷新浏览器,显示结果如下

如果我们此时点击任意一个 编辑 ,则会抛出 404 页面不存在错误

我们先来给 HomeController 添加一个 Edit 方法,接受一个 int 类型的 id 参数,然后返回一个 IActionResult 的结果,方法内容如下
[HttpGet]
public IActionResult Edit(int id)
{ var model = new HomePageViewModel();
SQLEmployeeData sqlData = new SQLEmployeeData(_context); Employee employee = sqlData.Get(id); if ( employee == null ) {
return RedirectToAction("Index");
} return View(employee);
}
这段代码出现了很多新面孔,比如 [HttpGet] 特性,有关 C# 特性的知识,请访问我们的 C# 基础教程:特性 ( Attribute )
ASP.NET Core 所有以 Http 开头的特性用于标识该方法只接受特定的 HTTP 请求方法
ASP.NET Core 支持下图七个 HTTP 请求方法特性

| 特性 | 说明 |
|---|---|
| HttpGet | 标识某个方法只支持 HTTP GET 请求方法 |
| HttpPut | 标识某个方法只支持 HTTP PUT 请求方法 |
| HttpHead | 标识某个方法只支持 HTTP HEAD 请求方法 |
| HttpPost | 标识某个方法只支持 HTTP POST 请求方法 |
| HttpPatch | 标识某个方法只支持 HTTP PATCH 请求方法 |
| HttpDelete | 标识某个方法只支持 HTTP DELETE 请求方法 |
| HttpOptions | 标识某个方法只支持 HTTP OPTIONS 请求方法 |
关于这些 HTTP 请求方法的介绍,可以访问我们的 HTTP 基础教程:HTTP 请求方法
第二个新面孔就是方法的返回值 IActionResult ,我们在 ASP.NET Core 动作结果 有提到,IActionResult 是所有返回结果的必须实现的接口,用这个作为返回值,也就是说该方法可以接受任意返回值。
第三个新面孔就是下面这段代码
if ( employee == null ) {
return RedirectToAction("Index");
}
意思是是如果 employee 的结果为空,也就是没有在数据库里找到 id 对应的记录,则重定向到 Index 方法,从某些方面说也就是重定向到首页
RedirectTo 家族非常庞大,数量之多,几乎涵盖了各种情况下的重定向

好了,重启我们的应用程序,然后刷新浏览器,自然,肯定是出错了,因为缺少对应的视图

那么,我们就在 Views/Home 下添加一个视图 Edit.cshtml 吧,添加方法和之前添加 Index.cshtml 、 Detail.cshtml 一样,我们就不做介绍了,然后输入以下内容
@model Employee
@{
ViewBag.Title = $"编辑 {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 = "保存" />
</div>
</form>
我们来解释下下面这段代码
保存我们的 Edit.cshtml,刷新浏览器,还是报错了。这次的错误是提示 Employee 类没有找到

修改 _ViewImports.cshtml 添加 @using HelloWorld.Models,添加完成后 _ViewImports.cshtml 的内容如下
@namespace HelloWorld.Views
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@using HelloWorld.Controllers
@using HelloWorld.Models
保存,然后刷新浏览器,这回显示正确了

当然了,不管我们是否编辑了员工姓名,如果点击保存,还是会报错,提示 404 不存在

这是因为我们刚刚添加的方法只适用于 HTTP GET 请求方法
我们需要再重载一个 Edit 方法用于接受 HTTP POST 请求
[HttpPost]
public IActionResult Edit(int id, EmployeeEditViewModel input)
{
SQLEmployeeData sqlData = new SQLEmployeeData( _context );
var employee = sqlData.Get(id); if (employee != null && ModelState.IsValid)
{
employee.Name = input.Name;
_context.SaveChanges();
return RedirectToAction("Detail", new { id = employee.ID });
}
return View(employee);
}
根据我们的路由规则,编辑表单应始终使用包含了 id 的 URL 来传递,如 /home/edit/1, 而显示表单和提交表单数据的最大差别就是 HTTP 请求方法,提交表单使用 [HttpPost] 特性
ASP.NET Core MVC 框架可以从 URL 中提起 id 数据并作为参数传递给动作方法
至于表单传递的其它数据,比如员工姓名,则使用另一个模型来接受不了,这个模型就是 EmployeeEditViewModel
EmployeeEditViewModel
EmployeeEditViewModel 用来从 HTTP POST 请求方法中接受传递的表单数据
那 EmployeeEditViewModel 到底长啥样呢,其实它跟 HomePageViewModel 差不多
我们再添加一下代码到 HomePageViewModel 后面
public class EmployeeEditViewModel {
[Required, MaxLength(80)]
public string Name { get; set; }
}
HomePageViewModel 包含了一个属性 Name,注意,Name 的名称和大小写必须和表单一模一样。
然后使用 C# 特性来限制 Name 字段必须输入数据 ( Required ),且数据的最大长度不得超过 80 ( MaxLength(80) )
因为表单只有一个字段 Name ,所以模型也就只有一个属性 Name,很简单,我们就不多做阐述了。
最后,使用 Required 等注解需要引入命名空间 System.ComponentModel.DataAnnotations `
ASP.NET Core MVC 参数模型绑定
回到 public IActionResult Edit(int id, EmployeeEditViewModel input) 方法,相比你也很好奇,ASP.NET Core MVC 是怎么给我们的 Edit 的两个参数传递实际的值的
我查阅了很多文档,原来 ASP.NET Core 使用了一种叫 模型绑定 的方法
模型绑定 是将 HTTP 请求的各种数据映射到动作方法参数的一种方法,参数即可以是简单类型,如字符串、整数或浮点数,也可以是复杂类型,如一个类。
模型绑定 查找数据源的顺序是
- Form values: 通过 HTTP POST 方法提交的数据,例如
Name - Route values: 路由器解析的参数,例如
id - Query String: URI 中的查询字符串部分的数据,也就是
?后面那一串
而模型绑定按照上面的顺序,只要找到了数据,就会停止继续查找。假设我们我们的 URI 为 /home/edit/1 ,而我们的表单有一个字段 id 值为 2 ,那么 Edit 方法的值为 2 而不是一,这是因为已经在 Form 表单中找到了 id 值,所以就不会继续查找了
对于复杂的数据,比如 HomePageViewModel,它的属性也是有要求的
- 要求接收数据的属性必须是
public的,如果不是,那么就没法注入值 - 要求必须有一个无参数的构造函数
当发生绑定时,类只会使用公共默认构造函数来实例化,然后在设置属性值。
ModelState
当一个参数绑定了数据后,模型绑定就会停止查找该名称的值,并继续绑定下一个参数。
如果某个参数绑定失败,那么 MVC 框架也不会抛出任何错误,而是设置 ModelState 的属性为 false,仅此而已
因此,我们可以通过检查 ModelState 的值来检查数据格式是否正确
_context.SaveChanges();
_context.SaveChanges(); 用于保存验证后的数据到数据库
其实 模型绑定 还有很多内容,但是限于篇幅,我们就不再继续了,如果你想深入阅读,可以查阅 ASP.NET 官方文档
运行范例
我们回到 HomeController.cs,当所有的修改完成后,完整的代码如下
HomeController
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.Linq; using HelloWorld.Models; namespace HelloWorld.Controllers
{
public class HomeController: Controller
{ private readonly HelloWorldDBContext _context; public HomeController(HelloWorldDBContext context)
{
_context = context;
} public ViewResult Index()
{ var model = new HomePageViewModel();
SQLEmployeeData sqlData = new SQLEmployeeData(_context);
model.Employees = sqlData.GetAll(); return View(model);
} public ViewResult Detail(int id)
{ var model = new HomePageViewModel();
SQLEmployeeData sqlData = new SQLEmployeeData(_context); Employee employee = sqlData.Get(id); return View(employee);
} [HttpGet]
public IActionResult Edit(int id)
{ var model = new HomePageViewModel();
SQLEmployeeData sqlData = new SQLEmployeeData(_context); Employee employee = sqlData.Get(id); if ( employee == null ) {
return RedirectToAction("Index");
} return View(employee);
} [HttpPost]
public IActionResult Edit(int id, EmployeeEditViewModel input)
{
SQLEmployeeData sqlData = new SQLEmployeeData( _context );
var employee = sqlData.Get(id); if (employee != null && ModelState.IsValid)
{
employee.Name = input.Name;
_context.SaveChanges();
return RedirectToAction("Detail", new { id = employee.ID });
}
return View(employee);
} } public class SQLEmployeeData
{
private HelloWorldDBContext _context { get; set; } public SQLEmployeeData(HelloWorldDBContext 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; }
}
}
保存 HomeController.cs,重启应用程序,然后刷新浏览器,结果如下

点击 ID 为 1 的 编辑,显示如下

我们将 李白 改成 李太白

点击保存

然后点击返回首页

ASP.NET Core MVC 的基础教程终于学习完了
ASP.NET Core Razor 编辑表单 - ASP.NET Core 基础教程 - 简单教程,简单编程的更多相关文章
- ASP.NET MVC 音乐商店 - 5. 通过支架创建编辑表单
在上一章,我们已经从数据库获取数据,然后显示出来,这一章,我们将允许编辑数据. 创建 StoreManagerController 控制器 我们将要创建称为 StoreManager 的控制器,对于这 ...
- ASP.NET MVC 3 之表单和 HTML 辅助方法(摘抄)
——选自<ASP.NET MVC3 高级编程(第5章) 孙远帅 译> 第5章 表单和HTML辅助方法 本章内容简介: * 理解表单 * 如何利用HTML辅助方法 * 编辑和输入的辅助方法 ...
- ASP.NET MVC3学习心得-----表单和HTML辅助方法
5.1表单的使用 5.1.1 action和method的特性 表单是包含输入元素的容器,包含按钮.复选框.文本框等元素,表单的这些输入元素使得用户能够向页面中输入信息,并把输入信息提交给服务器.A ...
- ASP.NET Web Pages:表单
ylbtech-.Net-ASP.NET Web Pages:表单 1.返回顶部 1. ASP.NET Web Pages - HTML 表单 表单是 HTML 文档中放置输入控件(文本框.复选框.单 ...
- C# Winform 通过FlowLayoutPanel及自定义的编辑控件,实现快速构建C/S版的编辑表单页面
个人理解,开发应用程序的目的,不论是B/S或是C/S结构类型,无非就是实现可供用户进行查.增.改.删,其中查询用到最多,开发设计的场景也最为复杂,包括但不限于:表格记录查询.报表查询.导出文件查询等等 ...
- Winform 通过FlowLayoutPanel及自定义的编辑控件,实现快速构建C/S版的编辑表单页面 z
http://www.cnblogs.com/zuowj/p/4504130.html 不论是B/S或是C/S结构类型,无非就是实现可供用户进行查.增.改.删,其中查询用到最多,开发设计的场景 也最为 ...
- atitit.提升开发效率---MDA 软件开发方式的革命(4)----编辑表单建模
)----编辑表单建模 1. 建模语言的选型anno+html...不是uml 1 2. 指定显示模板 @BeanEditForm(tmplt="c:/edit.html") 1 ...
- 【jQuery EasyUI系列】 创建展开行明细编辑表单的CRUD应用
当切换数据网络格局(datagrid view)到detailview,用户可以展开一行来显示一些行的明细在行下面,这个功能允许您为防止在明细行面板中的编辑表单提供一些合适的布局. 步骤1.在HTML ...
- atitit.编辑表单的实现最佳实践dwr jq easyui
atitit.编辑表单的实现最佳实践dwr jq easyui 1. 提交表单 1 2. 表单验证 1 3. 数据保存使用meger方式取代save&update方式 1 3.1. Filte ...
随机推荐
- 洛谷 偷天换日&&“访问”美术馆
典型的树形DP 按理说是先做“访问美术馆”再做偷天换日. 但是我先做了偷天换日然后再做的“访问”美术馆 DP方程好推,偷天换日在遇到有展品的时候做背包,因为是先做的偷天换日,所以把偷天换日的输入w,c ...
- hibernate---java.lang.UnsupportedOperationException: The user must supply a JDBC connection
在配置hibernate时.运行代码时一直抛错: Exception in thread "main" java.lang.UnsupportedOperationExce ...
- HBase -ROOT-和.META.表结构(region定位原理) 分类: B7_HBASE 2015-03-13 20:52 90人阅读 评论(0) 收藏
在HBase中,大部分的操作都是在RegionServer完成的,Client端想要插入,删除,查询数据都需要先找到相应的RegionServer.什么叫相应的RegionServer?就是管理你要操 ...
- C#操作SqlServer MySql Oracle通用帮助类
C#操作SqlServer MySql Oracle通用帮助类 [前言] 作为一款成熟的面向对象高级编程语言,C#在ADO.Net的支持上已然是做的很成熟,我们可以方便地调用ADO.Net操作各类关系 ...
- swift学习第七天:字典
字典的介绍 字典允许按照某个键来访问元素 字典是由两部分集合构成的,一个是键(key)集合,一个是值(value)集合 键集合是不能有重复元素的,而值集合是可以重复的,键和值是成对出现的 Swift中 ...
- 使用Apache FtpServer搭建FTP服务器 [FlashFXP]
<server xmlns="http://mina.apache.org/ftpserver/spring/v1" xmlns:xsi="http://www.w ...
- iis MP4 不能访问404
为什么我上传了flv或MP4文件到服务器,可输入正确地址通过http协议来访问总是出现“无法找到该页”的404错误呢?这就表明mp4格式文件是服务器无法识别的,其实,这是没有在iis中将相应的MIME ...
- 在Eclipse上打包并使用Proguard工具混淆jar包
近期由于工作须要,学习到了Android jar包的打包与混淆. 之前觉得还是非常easy的,可是自己深入研究下,发现还是有一些东西须要注意的,并且自己也踩了一些坑,在这里写下供同僚们借鉴借鉴. 转载 ...
- Photoshop怎么实现图片局部马赛克
学好ps是一件很重要的事情,作为日常必备技能,不管是在遇到这样的同时请求帮忙或者老板发配的任务的时候,就能分分钟派上用场了. 1:安装运行photoshop,点击文件-打开,选择要ps的图片. 图片. ...
- C++网络编程方面的开源项目
Webbench是一个在linux下使用的非常简单的网站压测工具.它使用fork()模拟多个客户端同时访问我们设定的URL,测试网站在压力下工作的性能,最多可以模拟3万个并发连接去测试网站的负载能力. ...