ASP.NET Core应用程序10:使用表单标签助手

news/2024/10/1 3:29:36

  本章描述用于创建 HTML 表单的内置标签助手。这些标签助手确保表单提交到正确的操作或页面处理程序方法,并确保元素准确地表示特定的模型属性。
本章解释 ASP.NET Core 提供的创建 HTML 表单的功能。展示如何使用标签助手来选择表单目标和关联的 imput、textarea 和 select 元素。

1 准备工作

  本章使用了前一章中的项目。
为准备这一章,替换 Views/Shared 文件夹的 _SimpleLayout.cshtml 文件中的内容。

<!DOCTYPE html>
<html>
<head><title>@ViewBag.Title</title><link href="/lib/twitter-bootstrap/css/bootstrap.min.css" rel="stylesheet" />
</head>
<body><div class="m-2">@RenderBody()</div>
</body>
</html>

  本章使用控制器视图和 Razor Pages 来呈现相似的内容。为了更容易区分控制器和页面,将如下所示的路由添加到 Startup 类中。

app.UseEndpoints(endpoints =>
{endpoints.MapControllers();endpoints.MapControllerRoute("forms","controllers/{controller=Home}/{action=Index}/{id?}");endpoints.MapDefaultControllerRoute();endpoints.MapRazorPages();
});

  新路由引入了一个静态路径段,使 URL 明显地以控制器为目标。使用浏览器请求http://localhost:5000/controllers/home/list,这会显示一个产品列表。

2 理解表单处理模式

  大多数 HTML 表单如下图所示处理数据。首先,浏览器发送一个 HTTP GET 请求,这会生成一个包含表单的 HTML 响应,使用户能够向应用程序提供数据。用户单击一个按钮使用 HTTP POST 请求提交表单数据,应用程序接收和处理用户的数据,处理完数据后发送一个响应将浏览器重定向到一个 URL,该 URL 提供了对用户操的确认。
image
这称为 Post/Redirect/Get 模式,这个重定向很重要,因为它意味着用户可以单击浏览器的 reload 按钮而不发送另一个 Post 请求,不然可能会导致无意中重复操作。

2.1 创建控制器来处理表单

  处理表单的控制器是通过结合前面章节中描述的特性创建的。在 Controllers 文件夹中添加一个名为 FormController.cs 的类文件。

public class FormController : Controller
{private DataContext context;public FormController(DataContext dbContext){context = dbContext;}public async Task<IActionResult> Index(long id = 1){return View("Form", await context.Products.FindAsync(id));}[HttpPost]public IActionResult SubmitForm(){var data = Request.Form.Keys.Where(k => !k.StartsWith(""));foreach (string key in data){TempData[key] = string.Join(",", Request.Form[key]);}return RedirectToAction(nameof(Results));}public IActionResult Results(){return View(TempData);}
}

  Index 操作方法选择一个名为 Form 的视图,它向用户呈现一个 HTML 表单。
当用户提交表单时,它由 SubmitForm 操作只能接收 HTTP POST 请求。这个操作方法处理通过 Request.Form 属性得到的 HTML 表单数据,以便可以使用临时数据特性存储它。每个表单数据值都以字符串数组的形式呈现,将其转换为以逗号分隔的字符串用于存储。浏览器重定向到 Results 操作方法,该方法选择默认视图并提供临时数据作为视图模型。

  创建 Views/From 文件夹,添加 From.cshtml 视图文件。

@model Product
@{Layout = "_SimpleLayout";
}<h5 class="bg-primary text-white text-center p-2">HTML Form</h5><form action="/controllers/form/submitform" method="post"><div class="form-group"><label>Name</label><input class="form-control" name="Name" value="@Model.Name" /></div><button type="submit" class="btn btn-primary">Submit</button>
</form>

  这个视图包含一个简单的 HTML 表单,配置为使用 POST 请求将数据提交给 Submitfom 方法。表单包含一个imput 元素,该元素的值是使用 Razor 表达式设置的。接下来给 Views/From 文件夹添加一个名为 Results.cshtml 的 Razor 视图。

@model TempDataDictionary
@{Layout = "_SimpleLayout";
}
<table class="table table-striped table-bordered table-sm"><thead><tr class="bg-primary text-white text-center"><th colspan="2">Form Data</th></tr></thead><tbody>@foreach (string key in Model.Keys){<tr><th>@key</th><td>@Model[key]</td></tr>}</tbody>
</table>
<a class="btn btn-primary" asp-action="Index">Return</a>

  这个视图向用户显示表单数据。并使用浏览器请求 http:/localhost:5000/controllers/form 以査看 HTML表单。在文本字段中输入一个值,并单击 Submit 发送一个 POST 请求,该请求将由 SubmitForm 操作处理。表单数据存储为临时数据,浏览器重定向。

2.2 创建 Razor Pages 来处理表单

  同样的模式可以使用 Razor Pages 实现。需要一个页面来呈现和处理表单数据,另一个页面显示结果。给 Pages 文件夹添加一个名为 FormHandler.cshtml 的 Razor Pages。

@page "/pages/form/{id:long?}"
@model FormHandlerModel
@using Microsoft.AspNetCore.Mvc.RazorPages<div class="m-2"><h5 class="bg-primary text-white text-center p-2">HTML Form</h5><form asp-page="FormHandler" method="post"><div class="form-group"><label>Name</label><input class="form-control" name="Name" value="@Model.Product.Name" /></div><button type="submit" class="btn btn-primary">Submit</button></form>
</div>@functions
{[IgnoreAntiforgeryToken]public class FormHandlerModel : PageModel{private DataContext context;public FormHandlerModel(DataContext dbContext){context = dbContext;}public Product Product { get; set; }public async Task OnGetAsync(long id = 1){Product = await context.Products.FindAsync(id);}public IActionResult OnPost(){foreach (string key inRequest.Form.Keys.Where(k => !k.StartsWith("_"))){TempData[key] = string.Join(", ", Request.Form[key]);}return RedirectToPage("FormResults");}}
}

  OnGetAsync 处理程序方法从数据库中检索 Product,视图使用该产品设置 HTML 表单中输入元素的值。该表单配置为发送一个将由 OnPost 处理程序方法处理的 HTTP POST 请求。表单数摊存储为临时数据,并向浏览器发送一个到 FormResults 表单的重定向。
要创建浏览器将被重定到的页面,向 Pages 文件夹添加一个名为 FormResults.cshtml 的 Razor Pages。

@page "/pages/results"<div class="m-2"><table class="table table-striped table-bordered table-sm"><thead><tr class="bg-primary text-white text-center"><th colspan="2">Form Data</th></tr></thead><tbody>@foreach (string key in TempData.Keys){<tr><th>@key</th><td>@TempData[key]</td></tr>}</tbody></table><a class="btn btn-primary" asp-page="FormHandler">Return</a>
</div>

  使用浏览器导航到 http:/localhost:5000/pages/form,在文本字段中输入一个值,然后单击 Submit 按钮。表单数据由 OnPost 方法处理,浏览器重定向到 /pages/results,从而显示表单数据。

3 使用标签助手改进HTML表单

  上面示例展示了处理 HTML 表单的基本机制,但是 ASP.NET Core 包含转换表单元素的标签助手。接下来描述标签助手并演示它们的用法。

3.1 使用表单元素

  FormTagHelper 类是表单元素的内置标签助手类,用于管理 HTML 表单的配置,以便它们能够针对正确的操作或页面处理程序,而不需要硬编码 URL。
表单元素的内置标签助手属性:

名称 描述
asp-controller 此属性用于为操作属性 URL 指定路由系统的 controller 值。如果省略,那么使用呈现视图的控制器
asp-action 此属性用于为 action属性 URL,的路由系统指定 action 值的操作方法。如果省略,就使用呈现视图的操作
asp-page 此属性用于指定 Razor Pages 的名称
asp-page-handler 此属性用于指定处理程序方法的名称,该处理程序方法用于处理请求。
asp-route-* 名称以 asp-route 开头的属性用于为操作属性 URL 指定附加值,以便使用 asp-route-id 属性为路由系统提供 id 段的值
asp-route 此属性指定将用于为操作生成 URL 属性的路由名称
asp-antiforgery 这个属性控制是否将防伪信息添加到视图中
asp-fragmen 此属性为生成的 URL 指定一个片段

设置表单目标
asp-action 属性用于指定将接收 HTTP 请求的操作的名称。修改在Views/Form 文件夹的 Form.cshtml 视图,以应用标签助手。

<form asp-action="submitform" method="post">

  asp-page 属性用于选择 Razor Pages 作为表单的目标。 在 Pages 文件夹的 FormHandler.cshtm 文件中设置表单目标。

<form asp-page="FormHandler" method="post">

3.2 改变表单按钮

  发送表单的按钮可以在表单元素之外定义。在这些情况下,按钮具有一个 form 属性,该属性的值对应于它所关联的表单元素的 id 属性,以及一个表单 action 属性,该属性指定表单的目标URL。

<form asp-action="submitform" method="post" id="htmlform"><div class="form-group"><label>Name</label><input class="form-control" name="Name" value="@Model.Name" /></div><button type="submit" class="btn btn-primary">Submit</button>
</form>
<button form="htmlform" asp-action="submitform" class="btn btn-primary mt-2">Sumit(Outside Form)
</button>

  添加到表单元素的 id 属性的值被按钮用作 form 属性的值,它告诉浏览器,在单击按钮时提交哪个表单。
也可用于 Razor Pages。

<form asp-page="FormHandler" method="post" id="htmlform"><div class="form-group"><label>Name</label><input class="form-control" name="Name" value="@Model.Product.Name" /></div><button type="submit" class="btn btn-primary">Submit</button>
</form>
<button form="htmlform" asp-page="FormHandler" class="btn btn-primary mt-2">Sumit(Outside Form)
</button>

  使用浏览器请求 http://localhost:5000/controllers/formhttp://localhost:5000/pages/form

4 处理 input 元素

  input 元素是 HTML 表单的主干,InputTagHelper 类用于转换 input 元素,以下属性反映它们要收集的视图模型属性的数据类型和格式。
input 元素的内置标签助手属性:

名称 描述
asp-for 这个属性用于指定 input 元素所表示的视图模型属性
asp-format 这个属性用于指定 input 元素所表示的视图模型属性的值的格式

  asp-for 属性设置为视图模型属性的名称,然后用于设置 input 元素的 name、id、type 和 value属性。在Views/Form 文件夹的 Form.cshtml 文件使用。

<label>Name</label>
@*<input class="form-control" name="Name" value="@Model.Name" />*@
<input class="form-control" asp-for="Name" />

  这个标签助手使用一个模型表达式,这就是为什么在指定 asp-for 属性的值时不使用@字符。如果査看在使用浏览器请求 http:/localhost:5000/controllers/form 时应用程序返回的 HTML,可看到标签助手将 input 元素转换为如下形式:

<input class="form-control" type="text" id="Name" name="Name" value="Kayak">

  id 和 name 属性的值是通过模型表达式获得的,从而确保在创建表单时不会引入拼写错误。

4.1 转换 input 元素的类型属性

  input 元素的 type 属性告诉浏览器如何显示元素,以及它应该如何限制用户输入的值。input 元素默认配置是 text 类型,没有任何输入限制。下面在 Views/Form 文件夹的 Form.cshtml 中 type 属性使用 number 类型。

<div class="form-group"><label>Id</label><input class="form-control" asp-for="ProductId" />
</div>

  新元素使用 asp-for 属性来选择视图模型的 Productld 属性。使用浏览器请求http://localhost:5000/controllers/form,查看标签助手转换的元素如下。

<input class="form-control" type="number" data-val="true" data-val-required="The ProductId field is required." id="ProductId" name="ProductId" value="1">

  type 属性的值由 asp-for 属性指定的视图模型属性的类型决定。ProductId属性的类型是 C# long类型,它导致标签助手将 input 元素的 type 属性设置为 number,这将限制元素使其只接收数字字符。data-val 和 data-val 所需的属性添加到 input 元素中帮助验证。也可以通过显式地定义 input 元素上的 type 属性可覆盖默认。

4.2 格式化 input 元素值

  当 action 方法为视图提供视图模型对象时,标签助手使用 asp-for 属性值来设置 input 元素的 value 属性。asp-format 属性用于指定数据值的格式。修改Form.cshtml。

<div class="form-group"><label>Price</label><input class="form-control" asp-for="Price" asp-format="{0:#,###.00}"/>
</div>

通过模型类应用格式化
如果总是希望对模型属性使用相同的格式,就可以使用 DisplayFommat 属性来装饰 C#类属性在 using System.ComponentModel.DataAnnotations名称空间中定义。Displayformat 属性需要两个数来格式化数据值:DisplayFormat 参数指定格式化字符串,将 ApplyformatnEdiMode设量为 true 意味着将值应用于编辑的元素(包括jmput 元素)时应该使用格式化。
在 Models 文件夹的 Product.cs 文件中应用格式化属性。

[DisplayFormat(DataFormatString = "{0:c2}", ApplyFormatInEditMode = true)]
public decimal Price { get; set; }

  asp-format 属性优先于 DisplayFormat 属性,因此从视图中删除该属性。并使用浏览器请求 http://localhost:5000/controllers/Form/index/5,会看到由属性定义的格式化字符串已经应用。

4.3 在 input 元素中显示相关数据的值

  在使用 Entity Framework Core 时,经常需要显示从相关数据中获得的数据值,使用 asp-for 属性很容易做到这一点,因为模型表达式允许选择嵌套的导航属性。
在 Controllers 文件夹的 FormController.cs 文件中包含相关数据。

public async Task<IActionResult> Index(long id = 1)
{var result = await context.Products.Include(p => p.Category).Include(p => p.Supplier).FirstAsync(p => p.ProductId == id);return View("Form", result);
}

  在Views/Form 文件夹的 Form.cshtml 文件中显示相关数据。

<div class="form-group"><label>Category</label><input class="form-control" asp-for="Category.Name" />
</div>
<div class="form-group"><label>Supplier</label><input class="form-control" asp-for="Supplier.Name" />
</div>

  asp-for 属性的值是相对于视图模型对象表示的,可以包含嵌套属性,允许选择EntityFramework Core 分配给 Category 和 Supplier 导航属性的相关对象的 Name 属性。Razor Pages 使用了相同的技术,只是属性是相对于页面模型对象表示的。

<div class="form-group"><label>Name</label><input class="form-control" asp-for="Product.Name" />
</div>
<div class="form-group"><label>Price</label><input class="form-control" asp-for="Product.Price" />
</div>
<div class="form-group"><label>Category</label><input class="form-control" asp-for="Product.Category.Name" />
</div>
<div class="form-group"><label>Supplier</label><input class="form-control" asp-for="Product.Supplier.Name" />
</div>......public async Task OnGetAsync(long id = 1)
{Product = await context.Products.Include(p => p.Category).Include(p => p.Supplier).FirstAsync(p => p.ProductId == id);
}

  使对控制器的更改生效,并使用浏览器请求 http://localhost:5000/controllers/form/index/5,和http://localhost:5000/pages/form

5 使用 label 元素

  LabelTagHelper 类用于转换 label 元素,因此 for 属性的设置与用于转换 input 元素的方法一致。
标签助手设置 label 元素的内容,以便它包含所选视图模型属性的名称。标签助手设置 for 属性,该属性表示与特定 input 元素的关联,并在单击关联的标签时使 input 元素获得焦点。
在 Views/Fomm 文件夹的 Form.cshtml 中,将 asp-for 属性应用于表单视图,以将每个 label 元素与表示相同视图模型属性的 imput 元素相关联。

<div class="form-group"><label asp-for="ProductId"></label><input class="form-control" asp-for="ProductId" />
</div>
<div class="form-group"><label asp-for="Name"></label><input class="form-control" asp-for="Name" />
</div>
<div class="form-group"><label asp-for="Price"></label><input class="form-control" asp-for="Price" />
</div>
<div class="form-group"><label asp-for="Category.Name">Category</label><input class="form-control" asp-for="Category.Name" />
</div>
<div class="form-group"><label asp-for="Supplier.Name">Supplier</label><input class="form-control" asp-for="Supplier.Name" />
</div>

6 使用 select 和 option 元素

  select 和 option 元素用于向用户提供一组固定的选择。
SelectTagHelper 负责转换 select 元素,并支持以下描述的属性。

名称 描述
asp-for 此属性用于指定 select 元素所表示的视图或页面模型属性
asp-items 此属性用于为 select 元素中包含的 option 元素指定值源

  在 Views/Form 文件夹的 Form.cshtml 中用 select 元素替换了类别的 input 元素。

<div class="form-group"><label asp-for="Category.Name">Category</label><select class="form-control" asp-for="CategoryId"><option value="1">Watersports</option><option value="2">Soccer</option><option value="3">Chess</option></select>
</div>

  所选的属性添加到 option 元素中,与视图模型的 CategoryId 值相对应。

<option value="2" selected="selected">Soccer</option>

  选择 option 元素的任务是由 OptionTagHelper 类执行的,该类通过 TagHelperContext. Items 集合接收来自 SelectTagHelper 的指令,结果是 select 元素显示与 Product 对象的 CategoryId 值相关联的类别名称。
填充 select 元素
asp-items 属性用于为标签助手提供 SelectListltem 对象的列表序列,为这些对象生成 option元素。在 Controllers 文件夹的 FormController.cs 的 Index方法, 修改表单控制器的索引操作,以通过视图包向视图提供一系列 SelectListltem 对象。

ViewBag.Categories = new SelectList(context.Categories, "CategoryId", "Name");

  可直接创建 SelectListltem 对象,但是 ASP.NET Core 提供了 SelectList 类来适应现有的数据序列。在本例中,从数据库中获得的 Category 对象序列传递给 SelectList 构造函数,还传递了应该用作 option 元素的值和标签的属性名称。在 Views/Form 文件夹的 Form.cshtml 中,更新了 form 视图以使用 SelectList。

<select class="form-control" asp-for="CategoryId" asp-items="@ViewBag.Categories">
</select>

7 处理文本区域

  textarea 元素用于从用户那里请求大量文本,TextAreaTagHelper 负贵转换 textarea 元素。
TextAreaTagHelper 相对简单,为 asp-for 属性提供的值用于设置 textarea 元素上的 id 和 name属性。asp-for属性选择的属性值用作textarea元素的内容。在 Vews/Fomm 文件夹的 Form.cshtm 替换了Supplier.Name属性的输入元素,带有已应用 asp-for 属性的文本区域。

<textarea class="form-control" asp-for="Supplier.Name"></textarea>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hjln.cn/news/45048.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

m基于PSO-GRU粒子群优化长门控循环单元网络的电力负荷数据预测算法matlab仿真

1.算法仿真效果 matlab2022a仿真结果如下:优化前: 优化后: 对比如下:2.算法涉及理论知识概要基于粒子群优化(Particle Swarm Optimization, PSO)和长门控循环单元(Gated Recurrent Unit, GRU)网络的电力负荷预测算法,是一种融合了优化技术和深度学习的先进预测模型。…

如何更改IIS中应用程序的虚拟路径

这边的虚拟路径查出来配置错了。 显示的是新建的时候的别名。修改目前我这边是删除重新加一个。

kali更换apt镜像

kali更换apt镜像 vim /etc/apt/sources.list进来之后按i进入编辑模式,把其他的镜像#注释掉之后,加上新的镜像,然后esc退出编辑,按:输入wq保存并退出! 上面的办法不知道为啥没用 修改 /etc/apt/sources.list 文件,也即修改镜像源,能够加快在下载和更新相关软件数据;否则…

数据结构与算法1 简要复习

1.三种复杂度 Ο,读音:big-oh;表示上界,小于等于。 Ω,读音:big omega、欧米伽;表示下界,大于等于。 Θ,读音:theta、西塔;既是上界也是下界,称为确界,等于。 2.抽象数据类型 3.堆,栈(queue,stack) 4.哈希线性探测 二次探测(重要) 二次哈希5.二叉搜索树(BS…

17岁中专女生爆冷逆袭全球数学竞赛12名

17岁中专女生自学偏微分方程,爆冷逆袭高分入围全球数学竞赛,获得竞赛第12名,兴趣是最好的老师。前言 兴趣是最好的老师。 看看她怎么说

seo如何优化

哈喽,大家好,我是木头左,物联网搬砖工一名,致力于为大家淘出更多好用的AI工具!SEO如何优化 一、了解SEO的基本概念 SEO(Search Engine Optimization),即搜索引擎优化,是指通过一系列技术手段,提高网站在搜索引擎中的自然排名,从而获得更多的免费流量。SEO的核心目标…

AI时代的创新工具:如何利用AI生成独具个性的XMind思维导图?

哈喽,大家好,我是木头左,物联网搬砖工一名,致力于为大家淘出更多好用的AI工具!背景 随着互联网的发展,越来越多的人开始使用Markdown来编写文档。Markdown是一种轻量级的标记语言,它允许人们使用简单的文本格式来编写文档,然后将其转换为HTML、PDF等格式。而思维导图则…

RSA

RSA 目录 简介 分类RSA密钥长度: RSA填充方案 RSA相关算法和协议: RSA与其他加密算法的结合: RSA的实现和优化:工作原理 算法实现Python C/C++实现待补充简介RSA加密算法是一种非对称加密算法,广泛用于安全通信。其核心思想基于数论中的大整数分解问题。 RSA算法在实际应用…