ASP.NET Core Razor 编辑表单 - ASP.NET Core 基础教程 - 简单教程,简单编程

简介: 原文:ASP.NET Core Razor 编辑表单 - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core Razor 编辑表单 上一章节我们介绍了标签助手和 HTML 助手,也使用标签助手和 HTML 助手分别创建了一个职工列表,感觉好像有点喜欢上标签助手和 HTML 助手了,正好之前我们只讲解了如何列出数据,没有讲解如何创建表单来添加和修改数据 要不本章节我们就来讲讲? 顺带多用用标签助手和 HTML 助手 本章中,我们将继续讨论标签助手。

原文: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> &nbsp; <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.cshtmlDetail.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 请求的各种数据映射到动作方法参数的一种方法,参数即可以是简单类型,如字符串、整数或浮点数,也可以是复杂类型,如一个类。

模型绑定 查找数据源的顺序是

  1. Form values: 通过 HTTP POST 方法提交的数据,例如 Name
  2. Route values: 路由器解析的参数,例如 id
  3. Query String: URI 中的查询字符串部分的数据,也就是 ? 后面那一串

而模型绑定按照上面的顺序,只要找到了数据,就会停止继续查找。假设我们我们的 URI 为 /home/edit/1 ,而我们的表单有一个字段 id 值为 2 ,那么 Edit 方法的值为 2 而不是一,这是因为已经在 Form 表单中找到了 id 值,所以就不会继续查找了

对于复杂的数据,比如 HomePageViewModel,它的属性也是有要求的

  1. 要求接收数据的属性必须是 public 的,如果不是,那么就没法注入值
  2. 要求必须有一个无参数的构造函数

当发生绑定时,类只会使用公共默认构造函数来实例化,然后在设置属性值。

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,重启应用程序,然后刷新浏览器,结果如下

点击 ID1编辑,显示如下

我们将 李白 改成 李太白

点击保存

然后点击返回首页

ASP.NET Core MVC 的基础教程终于学习完了

目录
相关文章
|
11天前
|
传感器 数据采集 物联网
探索.NET nanoFramework:为嵌入式设备编程的新途径
探索.NET nanoFramework:为嵌入式设备编程的新途
27 7
|
17天前
|
开发框架 NoSQL MongoDB
C#/.NET/.NET Core开发实战教程集合
C#/.NET/.NET Core开发实战教程集合
|
17天前
|
存储 NoSQL API
.NET NoSQL 嵌入式数据库 LiteDB 使用教程
.NET NoSQL 嵌入式数据库 LiteDB 使用教程~
|
2月前
|
开发框架 前端开发 JavaScript
ASP.NET MVC 教程
ASP.NET 是一个使用 HTML、CSS、JavaScript 和服务器脚本创建网页和网站的开发框架。
35 7
|
2月前
|
SQL 关系型数据库 数据库
七天.NET 8操作SQLite入门到实战详细教程(选型、开发、发布、部署)
七天.NET 8操作SQLite入门到实战详细教程(选型、开发、发布、部署)
|
3月前
|
大数据 开发工具 开发者
从零到英雄:.NET核心技术带你踏上编程之旅,构建首个应用,开启你的数字世界探险!
【8月更文挑战第28天】本文带领读者从零开始,使用强大的.NET平台搭建首个控制台应用。无论你是新手还是希望扩展技能的开发者,都能通过本文逐步掌握.NET的核心技术。从环境搭建到创建项目,再到编写和运行代码,详细步骤助你轻松上手。通过计算两数之和的小项目,你不仅能快速入门,还能为未来开发更复杂的应用奠定基础。希望本文为你的.NET学习之旅开启新篇章!
33 1
|
3月前
|
开发框架 JSON .NET
ASP.NET Core 标识(Identity)框架系列(三):在 ASP.NET Core Web API 项目中使用标识(Identity)框架进行身份验证
ASP.NET Core 标识(Identity)框架系列(三):在 ASP.NET Core Web API 项目中使用标识(Identity)框架进行身份验证
|
3月前
|
开发框架 .NET API
在IIS上部署ASP.NET Core Web API和Blazor Wasm详细教程
在IIS上部署ASP.NET Core Web API和Blazor Wasm详细教程
173 3
|
3月前
|
Java Spring 自然语言处理
Spring 框架里竟藏着神秘魔法?国际化与本地化的奇妙之旅等你来揭开谜底!
【8月更文挑战第31天】在软件开发中,国际化(I18N)与本地化(L10N)对于满足不同地区用户需求至关重要。Spring框架提供了强大支持,利用资源文件和`MessageSource`实现多语言文本管理。通过配置日期格式和货币符号,进一步完善本地化功能。合理应用这些特性,可显著提升应用的多地区适应性和用户体验。
35 0
|
3月前
|
传感器 数据采集 物联网
探索未来:.NET nanoFramework引领嵌入式设备编程革新之旅
【8月更文挑战第28天】.NET nanoFramework 是一款专为资源受限的嵌入式设备设计的轻量级、高性能框架,基于 .NET Core,采用 C# 进行开发,简化了传统底层硬件操作的复杂性,极大提升了开发效率。开发者可通过 Visual Studio 或 Visual Studio Code 快速搭建环境并创建项目,利用丰富的库和驱动程序轻松实现从基础 LED 控制到网络通信等多种功能,显著降低了嵌入式开发的门槛。
53 0

相关实验场景

更多