Asp.Net Core Tag Helpers 入门

Tag Helpers是ASP.NET Core中可重用的组件,可以将C#代码转换成HTML元素,使用Tag Helpers我们能启用服务器端代码参与创建和呈现客户端HTML元素,常用到Tag Helpers有asp-controller和asp-action用来生成url,例如:

<a asp-controller="Shop" asp-action="Clothes">Buy Clothes</a>

 将会生成 

<a href"/Shop/Clothes">Buy Clothes</a>

Tag Helpers有两种类型:

1 内置的Tag Helpers- 预先在框架内部定义好的,常用的一些功能有创建表单,HTM控件,显示验证消息等

2 客户自定义Tag Helpers- 你可以自己创建你希望转换的HTML元素

首先我们将查看一下内置的Tag Helpers,然后再解释如何创建自己的Tag Helpers

1 @addTagHelper

如果想在视图中使用Tag Helpers,必须使用@addTagHelper告诉Asp.Net Core运行时,打开Views/_ViewImports.cshtml 文件并且添加如下代码

@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

当我们在应用程序中使用自定义Tag Helpers,我们需要在_ViewImports.cshtml文件中添加如下代码:

@addTagHelper *, WebAppName

2 Tag Helpers 例子

我们为什么需要Tag Helpers? 因为我们可以加强对HTML元素的控制,通过从服务器端编写C#代码来添加额外的自定义逻辑,这些代码将参与在浏览器上呈现HTML标记,例如- 我们能够设计一个锚点标签使用相同颜色,字体和间距,而不在锚标签上使用class特性

在Visual Studio中创建一个新的app并且选择ASP.NET Core Web App MVC模版,项目命名为TagHelpers

8ae057f34fbfb5f7001efa27073e2570.png

创建完成之后,打开Views/_ViewImports.cshtml文件,我们发现Tag Helpers已经被添加

@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

注意:如果没有在Views/_ViewImports.cshtml文件中添加@addTagHelper指令,Asp.Net Core Tag Helpers不会工作,我们创建应用程序使用的ASP.NET Core MVC模版,因此 Visual Studio 自动添加Tag Helpers,如果我们创建应用程序使用空模版,我们需要自己添加这行代码

3 添加模型和仓储

在Models文件夹下添加一个Products.cs类,代码如下:

namespace AspNetCore.TagHelpers.Models
{
    public class Product
    {
        public string Name { get; set; }
        public float Price { get; set; }
        public int Quantity { get; set; }
    }
}

接下来,在Models文件夹内添加一个新的类Repository.cs,具体代码如下:

namespace AspNetCore.TagHelpers.Models
{
    public class Repository
    {
        public interface IRepository
        {
            IEnumerable<Product> Products { get; }
            void AddProduct(Product newProduct);
        }
        public class ProductRepository : IRepository
        {
            private List<Product> products = new List<Product> {
            new Product { Name = "Men Shoes", Price = 99.99F, Quantity= 100},
            new Product { Name = "Women Shoes", Price = 199.99F, Quantity= 200},
            new Product { Name = "Children Games", Price = 299.99F, Quantity= 300},
            new Product { Name = "Coats", Price = 399.99F, Quantity= 400},
        };
            public IEnumerable<Product> Products => products;
            public void AddProduct(Product newProduct)
            {
                products.Add(newProduct);
            }


        }
    }
}

这个类有IRepository接口包含两个成员-

1  一个IEnumerable属性迭代所有产品

2  一个AddProduct函数添加产品

我们定义了一个ProductRepository类实现IRepository接口,ProductRepository将产品存储到内存中,该类主要负责两件事:

1 存储产品到私有List,并且可以使用AddProduct方法向List中添加成员

2 有IEnumerable属性迭代所有产品

4 注册仓储服务

进入Program.cs并且将仓储服务注册为单例服务:

using static AspNetCore.TagHelpers.Models.Repository;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllersWithViews();
builder.Services.AddSingleton<IRepository, ProductRepository>();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/Error");
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");


app.Run();

5 控制器

修改HomeController代码,使用刚才我们注册的仓储,代码如下:

using AspNetCore.TagHelpers.Models;
using Microsoft.AspNetCore.Mvc;
using System.Diagnostics;
using static AspNetCore.TagHelpers.Models.Repository;
namespace AspNetCore.TagHelpers.Controllers
{
    public class HomeController : Controller
    {
        private IRepository _repository;
        private readonly ILogger<HomeController> _logger;
        public HomeController(IRepository repository,
            ILogger<HomeController> logger)
        {
            _repository = repository;
            _logger = logger;
        }
        public IActionResult Index()
        {
            return View(_repository.Products);
        }
        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 });
        }
    }
}

注意构造使用IRepository对象,依赖注入对象将自动创建ProductRepository当HomeController初始化时,Index方法仅仅返回IEunmerable属性包含所有仓储中所有产品

5 视图

修改Views/Home/Index.cshtml视图文件代码如下:

@model IEnumerable<Product>
<table class="table table-sm table-bordered">
    <thead class="bg-dark text-white">
        <tr>
            <th>Name</th>
            <th>Price</th>
            <th>Quantity</th>
        </tr>
    </thead>
    <tbody>
        @foreach (var product in Model)
        {
            <tr>
                <td>@product.Name</td>
                <td>@product.Price</td>
                <td>@product.Quantity</td>
            </tr>
        }
    </tbody>
</table>

在Home控制器的Index方法中,返回IEnumerable产品类型包含仓储类中所有产品,因此在视图中声明模型IEnumerable<Product>类型,我们在HTML表格内显示所有产品

注意代码内部的tbody我们循环通过所有产品创建一个单独的tr元素, 我们在表头使用了Bootstrap样式来做一些美化工作

运行应用程序,你将会看到所有产品显示在视图,图片如下:

2983e2a4a634eddc1ba22678128d20aa.png

6 内置 Anchor Tag Helper

锚点标签是使用最多的内置的Tag Helpers标签,它通过控制href来增强标准锚点标记,我们能够使用asp-controller,asp-action和asp-route-{value}特性创建href特性根据应用程序中定义的路由,例如在anchor标签下添加下面代码:

<a class="btn btn-primary" asp-controller="Home" asp-action="Create">Create new Product</a>

我们检查一下生成的HTML代码:

<a class="btn btn-primary" href="/Home/Create">Create new Product</a>

7 自定义Tag Helper

我们也可以定义一个自己的表格控件在视图中展示所有的产品,稍后我们添加一个

<MyTable Products="@Model"></MyTable>

针对这个客户自定义的表格我们能生成一个表格

为了创建这个自定义的Tag Helper,添加一个新的文件夹叫CustomTagHelpers在应用程序根目录下,接下来添加一个新的类MyTable.cs

在CustomTagHelpers目录下并且添加下面代码

using AspNetCore.TagHelpers.Models;
using Microsoft.AspNetCore.Razor.TagHelpers;
using System.Text;
namespace AspNetCore.TagHelpers.CustomTagHelpers
{
    [HtmlTargetElement("MyTable")]
    public class MyTable : TagHelper
    {
        public IEnumerable<Product> Products { get; set; }


        public override void Process(TagHelperContext context, TagHelperOutput output)
        {
            output.TagName = "table";
            output.TagMode = TagMode.StartTagAndEndTag;
            output.Attributes.SetAttribute("class", "table table-sm table-bordered");


            StringBuilder sb = new StringBuilder();
            foreach (var product in Products)
                sb.Append("<tr><td>" + @product.Name + "</td><td>" + @product.Price
                + "</td><td>" + @product.Quantity + "</td></tr>");


            output.Content.SetHtmlContent($@"<thead class=""bg-dark text-white"">
                                            <tr>
                                                <th>Name</th>
                                                <th>Price</th>
                                                <th>Quantity</th>
                                            </tr>
                                        </thead>
                                        {sb.ToString()}<tbody></tbody>");
        }
    }
}

客户自定义标签继承自TagHelper基类,我们已经定义了Products属性接收视图中products集合,接下来我们定义一个HTML表格来呈现所有产品

接下来我们添加自定义Tag Helper 在_ViewImports.cshtml文件,我们可以使用下面代码来完成:

@addTagHelper AspNetCore.TagHelpers.CustomTagHelpers.*, AspNetCore.TagHelpers

现在我们使用客户自定义的Tag Helper代码替换HTML页面table

<MyTable Products="@Model"></MyTable>

运行应用程序,你将发现呈现相同的HTML表格,这次我们只使用了一行代码,并且整个HTML表格将被呈现,这极大的改善了代码重用性

源代码地址

https://github.com/bingbing-gui/Asp.Net-Core-Skill/tree/master/Fundamentals/AspNetCore.TagHelpers/AspNetCore.TagHelpers

参考文献

[1]https://www.yogihosting.com/aspnet-core-introduction-tag-helpers/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值