ASP.NET Core 框架内置了大量的Tag Helpers,以asp-*前缀开始,他们用于加强表单,验证消息,计划结构等,在这节中昨们将继承讨论内置的Tag Helpers,比方表单控件,输入控件,选择控件,标签控件,锚点标签,文本控件,CSS,JS 和Cache1 Form资助标签
ASP.NET Core表单控件用来加强原始HTML表单的结实性和高效性,当业务发生变革时这些表单的可维护性很高,这些标志为表单天生action属性以及隐蔽的哀求验证令牌,以防止跨站点伪造哀求
下面给与了表单常用的资助标签
方法
| 形貌 |
asp-controller | 根据应用步伐的路由指定目的Controller,假如省略,利用当前视图文件地点的控制器 |
asp-action | 根据应用步伐的路由指定目的Action方法,假如省略,利用视图文件当前Action方法 |
asp-route-* | 指定url额外的段,比方 asp-route-id 利用提供id段的值 |
asp-route | 通过指定路由的名称天生action属性 |
asp-area | |
| 天生一个隐蔽的哀求验证令牌用来防止跨站点哀求攻击,常常和[ValidateAntiForgeryToken]特性一起利用,[ValidateAntiForgeryToken]利用在HTTP Post方法上 |
假如昨们的应用步伐只有一个路由界说在Programe.cs类中app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
<form method="post" asp-controller="Home" asp-action="Create">
...
</form>
在这种环境下表单的action方法将天生/Home/Create,昨们查抄一下表单中天生的HTML<form method="post" action="/Home/Create">
...
</form>
在应用步伐中的目次下Views->Home文件夹下创建一个新的视图文件,名字为Create.cshtml, 添加下面代码:
@model Product
@{
ViewData["Title"] = "新增";
}
<form method="post" asp-controller="Home" ,asp-action="Create">
<div class="mb-3 row">
<label class="col-sm-1 control-label" for="Name">名称:</label>
<div class="col-sm-11">
<input class="form-control" name="name" />
</div>
</div>
<div class="mb-3 row">
<label class="col-sm-1 control-label" for="Price">代价</label>
<div class="col-sm-11">
<input class="form-control" name="price" />
</div>
</div>
<div class="mb-3 row">
<label class="col-sm-1 control-label" for="Quantity">数目</label>
<div class="col-sm-11">
<input class="form-control" name="quantity" />
</div>
</div>
<div class="col-sm-11 offset-sm-1">
<button type="submit" class="btn btn-primary">新增</button>
</div>
</form>
昨们视图中创建一个form标签,利用asp-controller="Home"和asp-action="Create"资助标签创建html表单的action属性
表单的method是post,当提交表单时Create的方法被调用,在HomeController中添加2个Create方法,一个是HTTPGet别的一个是HttpPost
这两个Action方法的代码如下:
public IActionResult Create()
{
return View();
}
[HttpPost]
public IActionResult Create(Product product)
{
return RedirectToAction("Index");
}
昨们在label元素上利用for属性,用来绑定label元素,输入控件的name属性分别被赋值为-name,price&quantity,这些名称是Product.cs类的属性,昨们通过利用控件的名称来绑定action方法的参数运行应用步伐,你将会看到一个表单,在欣赏器中查抄表单位素而且你将看到action特性被创建为/Home/Create
提交表单新的产物将添加到repository,将会跳转到Index视图在产物列表表现全部的产物
留意:表单地点的Create视图位于HomeController中,对应的Action方法为Create,因此昨们也不必要应用asp-action和asp-controller资助标签<form method="post">
....
</form>
asp-antiforgery天生一个隐蔽的哀求验证令牌,这个令牌为antiforgerytoken,为了防止CSRF攻击,当你在你的表单上利用这个特性,ASP.NET Core做两件事:1 在表单的隐蔽域中添加一个安全的token
2 在相应添加一个cookie
假如表单中包罗Cookie和隐蔽的值,应用步伐将处置惩罚这个哀求,恶意站点不能访问,因此制止了CSRF
为了利用这个特性,在表单位素中添加资助标签asp-antiforgery="true", 而且在对应的哀求方法上添加[ValidateAntiForgeryToken]特性
@model Product
@{
ViewData["Title"] = "Create";
}
<form method="post" asp-controller="Home" asp-action="Create" asp-antiforgery="true">
// removed for clarity
</form>
在表单的Create视图中添加asp-antiforgery属性:
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Create(Product product)
{
return RedirectToAction("Index");
}
运行应用步伐而且查抄Create视图的HTML代码,你会在form元素内发现一个隐蔽域而且它包罗一个token值,如下所示:
如今打开Developer Tools, 进入Application页,接着在左边点击Cookies,你将会看到anti-forgery cookie,它将被一块发送到控制器
[ValidateAntiForgeryToken]特性将主动验证这个cookie和token2 Label资助标签
Label资助标签用来设置HTML中的Label,昨们在label上添加asp-for属性,在label标签上创建一个for属性,为了测试昨们在为Create视图中的Label添加asp-for属性
运行应用步伐,打开欣赏器查抄天生html源码

ASP.NET Core Input资助标签用来将输入元素绑定到模子表达式-asp-for="expression",当昨们在input输入控件中添加asp-for属性,input控件会利用模子表达式设置name,id,type和value属性的值,昨们修改Create视图中的Input元素for修改为asp-for运行应用步伐而且检察HTML源码,昨们发现input输入框包罗了id,name,type,value四个属性

你会发现Name和Price输入框的type是Text,但是Quantity输入框的范例是number,这是由于ASP.NET Core基于模子属性范例给HTML控件提供type的值
模子范例 | 输入框范例 |
byte, sbyte, int, uint, short, ushort, long, ulong | Number |
float, double, decimal | text |
string | text |
bool | checkbox |
DateTime | datetime |
4 Select资助标签
Select资助标签用来指定模子属性而且针对下拉框元素可选
1 asp-for 用模子属性名字设置为Select元素的id和name属性
2 asp-items 给Select元素提供可选的值
昨们把Create视图中quantity字段从输入框修改为选择框:

如今昨们查抄一下在欣赏器中天生的HTML代码,昨们看到把id和value的值设置为Product.cs类的Quantity属性,代码如下:

ASP.NET Core框架非常智能,选择控件可以或许主动选择默认值,为了相识它,添加Edit方法在Home控制器中,这个方法将从仓储中返回末了添加的记载,方法代码如下:public ViewResult Edit() => View("Create", _repository.Products.Last());
进入编辑页面的地点
https://localhost:7182/Home/Edit,昨们能清晰看到末了一条记载时400被主动选择在选择控件中

查抄天生的HTML源码,留意selected特性应用到了包罗400值的选项,代码如下:
4.1 asp-items 特性
asp-items 特性利用指定下拉框列表中的元素,它用来资助昨们从数据源天生下拉框列表中的元素,修改Create视图下拉框代码,如今利用asp-items特性:
<select class="form-control" asp-for="Quantity" asp-items="ViewBag.Quantity">
<option disabled selected value="">Select Quantity</option>
</select>
昨们指定ViewBag.Quantity作为asp-items特性的值,ViewBag将包罗一个SelectList对象将作为下拉框中的元素出现,如今修改Create和Edit方法using AspNetCore.BuiltInTagHelpers.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using System.Diagnostics;
using static AspNetCore.BuiltInTagHelpers.Models.Repository;
namespace AspNetCore.BuiltInTagHelpers.Controllers
{
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
private readonly IRepository _repository;
public HomeController(IRepository repository,
ILogger<HomeController> logger)
{
_repository = repository;
_logger = logger;
}
public ViewResult Edit()
{
ViewBag.Quantity = new SelectList(_repository.Products.Select(p => p.Quantity).Distinct());
return View("Create", _repository.Products.Last());
}
public IActionResult Index()
{
return View(_repository.Products);
}
public IActionResult Create()
{
ViewBag.Quantity = new SelectList(_repository.Products.Select(p => p.Quantity).Distinct());
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Create(Product product)
{
_repository.AddProduct(product);
return RedirectToAction("Index");
}
public IActionResult Privacy()
{
return View();
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
}
}
ViewBag.Quantity 属性设置为SelectList 对象,利用仓储Quantity值来添补该对象,颠末这么一番修改,昨们实现了动态选择
SelectList对象位于Microsoft.AspNetCore.Mvc.Rendering定名空间运行应用步伐,哀求 https://localhost:7076/Home/Create 大概https://localhost:7076/Home/Edit 地点,这次你会发现可选元素被创建在ViewBag.Quantity数据源5 Cache资助标签
Cache资助标签利用缓存内容用来资助进步应用步伐的性能,你可以将内容添加到缓存标签内部:<cache> Some Content </cache>
进入_Layout.cshtml文件而且添加cache元素用来缓存当前时间: <div class="container">
<main role="main" class="pb-3">
<div class="bg-info text-warning">
<cache>
Date Time: @DateTime.Now.ToString("HH:mm:ss")
</cache>
</div>
@RenderBody()
</main>
</div>
如今运行应用步伐,你将会看到当前时间表现在页面顶部,如下图所示:

如今革新页面而且昨们将看到时间在小时,分钟,秒没有任何变革,这是由于时间被缓存了
名称 | 形貌 |
expires-on | 给缓存指定一个逾期的绝对时间 |
expires-after | 指定一个缓存逾期的相对时间,TimeSpan值 |
expires-sliding | 滑动时间,末了一次利用时间短, 它指定TimeSpan值中缓存逾期的滑动时间 |
vary-by-query | 一个查询字符串的键,被用来管理差别版本的缓存 |
vary-by-cookie | 一个cookie名称用来管理差别版本的缓存 |
vary-by | 指定一个key用来管理差别版本的缓存 |
5.1 expires-after
在_layout.cshtml文件中为缓存代码添加expires-after特性:
<cache expires-after="@TimeSpan.FromSeconds(20)">
Date Time: @DateTime.Now.ToString("HH:mm:ss")
</cache>
5.2 expires-on
在_layout.cshtml文件中为缓存代码添加expires-on特性:
<cache expires-on="@DateTime.Parse("2050-01-01")">
Date Time: @DateTime.Now.ToString("HH:mm:ss")
</cache>
时间被缓存直到2025年
在_Layout.cshmtl视图为缓存代码添加expires-sliding特性<cache expires-sliding="@TimeSpan.FromSeconds(20)" >
Date Time: @DateTime.Now.ToString("HH:mm:ss")
</cache>
这个缓存将在间隔前次利用的20s后逾期
为了测试,每两秒加载一次页面,你将会看到雷同的时间,等候20秒之后重新加载页面,这时你将看到一个新的时间,这时由于这个缓存在末了一次加载时间20s之后逾期
5.4 vary-by
vary-by特性利用指定一个key来管理差别版本的缓存,在_Layout.cshtml视图修改cache元素:
<cache expires-sliding="@TimeSpan.FromSeconds(20)" vary-by="@ViewContext.RouteData.Values["action"]">
Date Time: @DateTime.Now.ToString("HH:mm:ss")
</cache>
这意味着cache是基于当前action,昨们有三个actions-Index,Edit和Create,因此3个版本的缓存将被创建(每个action方法都有一个),expire-sliding特性为每个版本设置滑动时间
Anchor资助标签利用最广泛的内置资助标签在ASP.NET Core框架,通过添加新的特性来增强anchor标签,这个特性基于应用步伐路由构建anchor标签href
下面表格枚举出紧张的标签被利用通过anchor 资助标签
| 形貌 |
asp-controller | 指定url将被定位到的控制器 |
asp-action | 指定url将被定位到的action |
asp-area | 指定url将被定位到的area |
asp-fragment | 指定url段(在#字符背面) |
asp-route | 指定url将被定位到的路由名称 |
asp-route-* | 指定额外的值针对url 比方asp-route-id="10"为路由段提供了一个id为10的值 |
进入Index视图而且创建一个链接定位到Create视图:@{
ViewData["Title"] = "Home Page";
}
@model IEnumerable<Product>
<div class="container">
<div class="row mb-3">
<div class="col-sm-3">
<a class="btn btn-primary" asp-action="Create">新增</a>
</div>
<div class="col-sm-3"></div>
<div class="col-sm-3"></div>
<div class="col-sm-3"></div>
</div>
<div class="row mb-3">
<div class="col-sm">
<table class="table table-bordered align-middle">
<thead>
<tr>
<th>名称</th>
<th>代价</th>
<td>数目</td>
</tr>
</thead>
<tbody>
@foreach (var product in Model)
{
<tr>
<td>@product.Name</td>
<td>@product.Price</td>
<td>@product.Quantity</td>
</tr>
}
</tbody>
</table>
</div>
</div>
</div>
<a class="btn btn-primary" href="/Home/Create">新增</a>
邀请