Bagikan melalui


Komponen Pembantu Tag di ASP.NET Core

Oleh Scott Addie dan Fiyaz Bin Hasan

Komponen Pembantu Tag adalah Pembantu Tag yang memungkinkan Anda memodifikasi atau menambahkan elemen HTML secara kondisional dari kode sisi server. Fitur ini tersedia di ASP.NET Core 2.0 atau yang lebih baru.

ASP.NET Core mencakup dua Komponen Pembantu Tag bawaan: head dan body. Mereka terletak di Microsoft.AspNetCore.Mvc.Razor.TagHelpers namespace layanan dan dapat digunakan di MVC dan Razor Pages. Komponen Pembantu Tag tidak memerlukan pendaftaran dengan aplikasi di _ViewImports.cshtml.

Melihat atau mengunduh kode sampel (cara mengunduh)

Kasus penggunaan

Dua kasus penggunaan umum Komponen Pembantu Tag meliputi:

  1. Menyuntikkan <link> ke dalam <head>.
  2. Menyuntikkan <script> ke dalam <body>.

Bagian berikut menjelaskan kasus penggunaan ini.

Menyuntikkan ke dalam elemen kepala HTML

Di dalam elemen HTML <head> , file CSS umumnya diimpor dengan elemen HTML <link> . Kode berikut menyuntikkan <link> elemen ke <head> dalam elemen menggunakan Komponen Pembantu head Tag:

using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Razor.TagHelpers;

namespace RazorPagesSample.TagHelpers
{
    public class AddressStyleTagHelperComponent : TagHelperComponent
    {
        private readonly string _style = 
            @"<link rel=""stylesheet"" href=""/css/address.css"" />";

        public override int Order => 1;

        public override Task ProcessAsync(TagHelperContext context,
                                          TagHelperOutput output)
        {
            if (string.Equals(context.TagName, "head", 
                              StringComparison.OrdinalIgnoreCase))
            {
                output.PostContent.AppendHtml(_style);
            }

            return Task.CompletedTask;
        }
    }
}

Dalam kode sebelumnya:

  • AddressStyleTagHelperComponent penerapan TagHelperComponent. Abstraksi:
    • Memungkinkan inisialisasi kelas dengan TagHelperContext.
    • Memungkinkan penggunaan Komponen Pembantu Tag untuk menambahkan atau mengubah elemen HTML.
  • Properti Order menentukan urutan di mana Komponen dirender. Order diperlukan ketika ada beberapa penggunaan Komponen Pembantu Tag dalam aplikasi.
  • ProcessAsync membandingkan nilai properti konteks TagName eksekusi dengan head. Jika perbandingan mengevaluasi ke true, konten _style bidang disuntikkan ke dalam elemen HTML <head> .

Menyuntikkan ke dalam elemen isi HTML

Komponen Pembantu body Tag dapat menyuntikkan <script> elemen ke <body> dalam elemen . Kode berikut menunjukkan teknik ini:

using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Razor.TagHelpers;

namespace RazorPagesSample.TagHelpers
{
    public class AddressScriptTagHelperComponent : TagHelperComponent
    {
        public override int Order => 2;
        
        public override async Task ProcessAsync(TagHelperContext context,
                                                TagHelperOutput output)
        {
            if (string.Equals(context.TagName, "body",
                              StringComparison.OrdinalIgnoreCase))
            {
                var script = await File.ReadAllTextAsync(
                    "TagHelpers/Templates/AddressToolTipScript.html");
                output.PostContent.AppendHtml(script);
            }
        }
    }
}

File HTML terpisah digunakan untuk menyimpan <script> elemen . File HTML membuat kode lebih bersih dan lebih dapat dipertahankan. Kode sebelumnya membaca konten TagHelpers/Templates/AddressToolTipScript.html dan menambahkannya dengan output Tag Helper. File AddressToolTipScript.html menyertakan markup berikut:

<script>
$("address[printable]").hover(function() {
    $(this).attr({
        "data-toggle": "tooltip",
        "data-placement": "right",
        "title": "Home of Microsoft!"
    });
});
</script>

Kode sebelumnya mengikat widget tipsalat Bootstrap ke elemen apa pun <address> yang menyertakan printable atribut. Efeknya terlihat ketika penunjuk mouse mengarah ke elemen.

Daftarkan Komponen

Komponen Pembantu Tag harus ditambahkan ke koleksi Komponen Pembantu Tag aplikasi. Ada tiga cara untuk menambahkan ke koleksi:

Pendaftaran melalui kontainer layanan

Jika kelas Komponen Pembantu Tag tidak dikelola dengan ITagHelperComponentManager, kelas tersebut harus terdaftar dengan sistem injeksi dependensi (DI ). Kode berikut Startup.ConfigureServices mendaftarkan AddressStyleTagHelperComponent kelas dan AddressScriptTagHelperComponent dengan masa pakai sementara:

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<CookiePolicyOptions>(options =>
    {
        options.CheckConsentNeeded = context => true;
        options.MinimumSameSitePolicy = SameSiteMode.None;
    });

    services.AddMvc()
            .SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

    services.AddTransient<ITagHelperComponent, 
        AddressScriptTagHelperComponent>();
    services.AddTransient<ITagHelperComponent, 
        AddressStyleTagHelperComponent>();
}

Pendaftaran melalui Razor file

Jika Komponen Pembantu Tag tidak terdaftar di DI, komponen tersebut dapat didaftarkan dari Razor halaman Halaman atau tampilan MVC. Teknik ini digunakan untuk mengontrol markup yang disuntikkan dan urutan eksekusi komponen dari Razor file.

ITagHelperComponentManager digunakan untuk menambahkan Komponen Pembantu Tag atau menghapusnya dari aplikasi. Kode berikut menunjukkan teknik ini dengan AddressTagHelperComponent:

@using RazorPagesSample.TagHelpers;
@using Microsoft.AspNetCore.Mvc.Razor.TagHelpers;
@inject ITagHelperComponentManager manager;

@{
    string markup;

    if (Model.IsWeekend)
    {
        markup = "<em class='text-warning'>Office closed today!</em>";
    }
    else
    {
        markup = "<em class='text-info'>Office open today!</em>";
    }

    manager.Components.Add(new AddressTagHelperComponent(markup, 1));
}

Dalam kode sebelumnya:

  • Direktif @inject menyediakan instans ITagHelperComponentManager. Instans ditetapkan ke variabel bernama manager untuk akses hilir dalam Razor file.
  • Instans ditambahkan ke koleksi Komponen Pembantu AddressTagHelperComponent Tag aplikasi.

AddressTagHelperComponent dimodifikasi untuk mengakomodasi konstruktor yang menerima markup parameter dan order :

private readonly string _markup;

public override int Order { get; }

public AddressTagHelperComponent(string markup = "", int order = 1)
{
    _markup = markup;
    Order = order;
}

Parameter yang disediakan markup digunakan sebagai ProcessAsync berikut:

public override async Task ProcessAsync(TagHelperContext context,
                                        TagHelperOutput output)
{
    if (string.Equals(context.TagName, "address",
            StringComparison.OrdinalIgnoreCase) &&
        output.Attributes.ContainsName("printable"))
    {
        TagHelperContent childContent = await output.GetChildContentAsync();
        string content = childContent.GetContent();
        output.Content.SetHtmlContent(
            $"<div>{content}<br>{_markup}</div>{_printableButton}");
    }
}

Pendaftaran melalui Model Halaman atau pengontrol

Jika Komponen Pembantu Tag tidak terdaftar di DI, komponen tersebut dapat didaftarkan dari Razor model halaman Pages atau pengontrol MVC. Teknik ini berguna untuk memisahkan logika C# dari Razor file.

Injeksi konstruktor digunakan untuk mengakses instans ITagHelperComponentManager. Komponen Pembantu Tag ditambahkan ke koleksi Komponen Pembantu Tag instans. Model halaman Halaman berikut Razor menunjukkan teknik ini dengan AddressTagHelperComponent:

using System;
using Microsoft.AspNetCore.Mvc.Razor.TagHelpers;
using Microsoft.AspNetCore.Mvc.RazorPages;
using RazorPagesSample.TagHelpers;

public class IndexModel : PageModel
{
    private readonly ITagHelperComponentManager _tagHelperComponentManager;

    public bool IsWeekend
    {
        get
        {
            var dayOfWeek = DateTime.Now.DayOfWeek;

            return dayOfWeek == DayOfWeek.Saturday ||
                   dayOfWeek == DayOfWeek.Sunday;
        }
    }

    public IndexModel(ITagHelperComponentManager tagHelperComponentManager)
    {
        _tagHelperComponentManager = tagHelperComponentManager;
    }

    public void OnGet()
    {
        string markup;

        if (IsWeekend)
        {
            markup = "<em class='text-warning'>Office closed today!</em>";
        }
        else
        {
            markup = "<em class='text-info'>Office open today!</em>";
        }

        _tagHelperComponentManager.Components.Add(
            new AddressTagHelperComponent(markup, 1));
    }
}

Dalam kode sebelumnya:

  • Injeksi konstruktor digunakan untuk mengakses instans ITagHelperComponentManager.
  • Instans ditambahkan ke koleksi Komponen Pembantu AddressTagHelperComponent Tag aplikasi.

Membuat Komponen

Untuk membuat Komponen Pembantu Tag kustom:

Kode berikut membuat Komponen Pembantu Tag kustom yang menargetkan <address> elemen HTML:

using System.ComponentModel;
using Microsoft.AspNetCore.Mvc.Razor.TagHelpers;
using Microsoft.AspNetCore.Razor.TagHelpers;
using Microsoft.Extensions.Logging;

namespace RazorPagesSample.TagHelpers
{
    [HtmlTargetElement("address")]
    [EditorBrowsable(EditorBrowsableState.Never)]
    public class AddressTagHelperComponentTagHelper : TagHelperComponentTagHelper
    {
        public AddressTagHelperComponentTagHelper(
            ITagHelperComponentManager componentManager, 
            ILoggerFactory loggerFactory) : base(componentManager, loggerFactory)
        {
        }
    }
}

Gunakan Komponen Pembantu Tag kustom address untuk menyuntikkan markup HTML sebagai berikut:

public class AddressTagHelperComponent : TagHelperComponent
{
    private readonly string _printableButton =
        "<button type='button' class='btn btn-info' onclick=\"window.open(" +
        "'https://binged.it/2AXRRYw')\">" +
        "<span class='glyphicon glyphicon-road' aria-hidden='true'></span>" +
        "</button>";

    public override int Order => 3;

    public override async Task ProcessAsync(TagHelperContext context,
                                            TagHelperOutput output)
    {
        if (string.Equals(context.TagName, "address",
                StringComparison.OrdinalIgnoreCase) &&
            output.Attributes.ContainsName("printable"))
        {
            var content = await output.GetChildContentAsync();
            output.Content.SetHtmlContent(
                $"<div>{content.GetContent()}</div>{_printableButton}");
        }
    }
}

Metode sebelumnya menyuntikkan ProcessAsync HTML yang disediakan ke SetHtmlContent dalam elemen pencocokan <address> . Injeksi terjadi ketika:

  • Nilai properti konteks TagName eksekusi sama dengan address.
  • Elemen yang <address> sesuai memiliki printable atribut .

Misalnya, if pernyataan mengevaluasi ke true saat memproses elemen berikut <address> :

<address printable>
    One Microsoft Way<br />
    Redmond, WA 98052-6399<br />
    <abbr title="Phone">P:</abbr>
    425.555.0100
</address>

Sumber Daya Tambahan: