Aracılığıyla paylaş


ASP.NET Core'da Etiket Yardımcısı Bileşenleri

Tarafından Scott Addie ve Fiyaz Bin Hasan

Etiket Yardımcısı Bileşeni, sunucu tarafı koddan HTML öğelerini koşullu olarak değiştirmenize veya eklemenize olanak tanıyan bir Etiket Yardımcısıdır. Bu özellik ASP.NET Core 2.0 veya sonraki sürümlerinde kullanılabilir.

ASP.NET Core iki yerleşik Etiket Yardımcısı Bileşeni içerir: head ve body. Ad alanında Microsoft.AspNetCore.Mvc.Razor.TagHelpers bulunurlar ve hem MVC'de Razor hem de Sayfalarda kullanılabilirler. Etiket Yardımcısı Bileşenleri' nde _ViewImports.cshtmluygulamayla kayıt gerektirmez.

Örnek kodu görüntüleme veya indirme (indirme)

Kullanım örnekleri

Etiket Yardımcısı Bileşenlerinin iki yaygın kullanım örneği şunlardır:

  1. içine bir <link> ekleme <head>.
  2. içine bir <script> ekleme <body>.

Aşağıdaki bölümlerde bu kullanım örnekleri açıklanmaktadır.

HTML baş öğesine ekleme

HTML <head> öğesinin içinde CSS dosyaları genellikle HTML <link> öğesiyle içeri aktarılır. Aşağıdaki kod, Etiket Yardımcısı Bileşeni'ni <head>head kullanarak öğesine bir <link> öğe ekler:

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;
        }
    }
}

Önceki kodda:

  • AddressStyleTagHelperComponent uygular TagHelperComponent. Özet:
    • ile TagHelperContextsınıfının başlatılmasına izin verir.
    • HTML öğeleri eklemek veya değiştirmek için Etiket Yardımcısı Bileşenlerinin kullanılmasını sağlar.
  • özelliği, Order Bileşenlerin işlenme sırasını tanımlar. Order bir uygulamada Etiket Yardımcısı Bileşenlerinin birden çok kullanımı olduğunda gereklidir.
  • ProcessAsync yürütme bağlamı TagName özellik değerini ile headkarşılaştırır. Karşılaştırma true olarak değerlendirilirse, alanın içeriği _style HTML <head> öğesine eklenir.

HTML gövde öğesine ekleme

body Etiket Yardımcısı Bileşeni, öğeye <body> bir <script> öğe ekleyebilir. Aşağıdaki kod bu tekniği gösterir:

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);
            }
        }
    }
}

öğesini depolamak <script> için ayrı bir HTML dosyası kullanılır. HTML dosyası kodu daha temiz ve daha sürdürülebilir hale getirir. Yukarıdaki kod içeriğini TagHelpers/Templates/AddressToolTipScript.html okur ve Etiket Yardımcısı çıkışıyla ekler. Dosya AddressToolTipScript.html aşağıdaki işaretlemeyi içerir:

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

Yukarıdaki kod, bir Bootstrap araç ipucu pencere öğesini öznitelik içeren herhangi <address> bir printable öğeye bağlar. Fare işaretçisi öğenin üzerine geldiğinde efekt görünür.

Bileşen Kaydetme

Uygulamanın Etiket Yardımcısı Bileşenleri koleksiyonuna bir Etiket Yardımcısı Bileşeni eklenmelidir. Koleksiyona eklemenin üç yolu vardır:

Hizmetler kapsayıcısı aracılığıyla kayıt

Etiket Yardımcısı Bileşeni sınıfı ile ITagHelperComponentManageryönetilmiyorsa, bağımlılık ekleme (DI) sistemine kayıtlı olmalıdır. Aşağıdaki Startup.ConfigureServices kod, ve AddressScriptTagHelperComponent sınıflarını AddressStyleTagHelperComponent geçici bir yaşam süresiyle kaydeder:

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>();
}

Dosya aracılığıyla Razor kayıt

Etiket Yardımcısı Bileşeni DI'ye kayıtlı değilse, sayfalar Razor sayfasından veya MVC görünümünden kaydedilebilir. Bu teknik, eklenen işaretlemeyi ve bileşen yürütme sırasını bir Razor dosyadan denetlemek için kullanılır.

ITagHelperComponentManager Etiket Yardımcısı Bileşenleri eklemek veya bunları uygulamadan kaldırmak için kullanılır. Aşağıdaki kod ile AddressTagHelperComponentbu tekniği gösterir:

@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));
}

Önceki kodda:

  • yönergesi @inject bir örneği ITagHelperComponentManagersağlar. Örnek, dosyada erişim aşağı akışı için adlı manager bir değişkene Razor atanır.
  • Uygulamasının Etiket Yardımcısı Bileşenleri koleksiyonuna bir örneği AddressTagHelperComponent eklenir.

AddressTagHelperComponentve order parametrelerini kabul eden bir oluşturucuyu markup barındıracak şekilde değiştirilir:

private readonly string _markup;

public override int Order { get; }

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

Sağlanan markup parametre şu ProcessAsync şekilde kullanılır:

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}");
    }
}

Sayfa Modeli veya denetleyici aracılığıyla kayıt

Etiket Yardımcısı Bileşeni DI'ye kayıtlı değilse, bir Razor Sayfalar sayfa modelinden veya MVC denetleyicisinden kaydedilebilir. Bu teknik, C# mantığını dosyalardan Razor ayırmak için kullanışlıdır.

Oluşturucu ekleme, örneğine ITagHelperComponentManagererişmek için kullanılır. Etiket Yardımcısı Bileşeni, örneğin Etiket Yardımcısı Bileşenleri koleksiyonuna eklenir. Aşağıdaki Razor Sayfalar sayfa modeli ile AddressTagHelperComponentbu tekniği gösterir:

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));
    }
}

Önceki kodda:

  • Oluşturucu ekleme, örneğine ITagHelperComponentManagererişmek için kullanılır.
  • Uygulamasının Etiket Yardımcısı Bileşenleri koleksiyonuna bir örneği AddressTagHelperComponent eklenir.

Bileşen Oluşturma

Özel Etiket Yardımcısı Bileşeni oluşturmak için:

Aşağıdaki kod, HTML öğesini hedefleyen <address> özel bir Etiket Yardımcısı Bileşeni oluşturur:

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)
        {
        }
    }
}

HTML işaretlemesini eklemek için aşağıdaki gibi özel address Etiket Yardımcısı Bileşenini kullanın:

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}");
        }
    }
}

Yukarıdaki ProcessAsync yöntem, sağlanan HTML'yi eşleşen <address> öğeye SetHtmlContent ekler. Ekleme şu durumlarda gerçekleşir:

  • Yürütme bağlamı TagName özellik değeri eşittir address.
  • <address> İlgili öğenin bir printable özniteliği vardır.

Örneğin, if aşağıdaki <address> öğe işlenirken deyimi true olarak değerlendirilir:

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

Ek kaynaklar