Tworzenie pomocników tagów w programie ASP.NET Core
Autor: Rick Anderson
Wyświetl lub pobierz przykładowy kod (jak pobrać)
Wprowadzenie do pomocników tagów
Ten samouczek zawiera wprowadzenie do pomocników tagów programowania. Wprowadzenie do pomocników tagów opisuje korzyści zapewniane przez pomocników tagów.
Pomocnik tagów to dowolna klasa, która implementuje ITagHelper
interfejs. Jednak podczas tworzenia pomocnika tagów zazwyczaj pochodzisz z TagHelper
metody , dzięki czemu uzyskujesz dostęp do Process
metody .
Utwórz nowy projekt ASP.NET Core o nazwie AuthoringTagHelpers. W tym projekcie nie będzie potrzebne uwierzytelnianie.
Utwórz folder do przechowywania pomocników tagów o nazwie TagHelpers. Folder TagHelpers nie jest wymagany, ale jest to rozsądna konwencja. Teraz zacznijmy pisać kilka prostych pomocników tagów.
Pomocnik tagu minimalnego
W tej sekcji napiszesz pomocnik tagu, który aktualizuje tag e-mail. Przykład:
<email>Support</email>
Serwer użyje naszego pomocnika tagów poczty e-mail, aby przekonwertować ten znacznik na następujące elementy:
<a href="mailto:Support@contoso.com">Support@contoso.com</a>
Oznacza to, że tag kotwicy, który sprawia, że jest to link do wiadomości e-mail. Możesz to zrobić, jeśli piszesz aparat blogów i potrzebujesz go do wysyłania wiadomości e-mail na potrzeby marketingu, pomocy technicznej i innych kontaktów, a wszystko to do tej samej domeny.
Dodaj następującą
EmailTagHelper
klasę do folderu TagHelpers .using Microsoft.AspNetCore.Razor.TagHelpers; using System.Threading.Tasks; namespace AuthoringTagHelpers.TagHelpers { public class EmailTagHelper : TagHelper { public override void Process(TagHelperContext context, TagHelperOutput output) { output.TagName = "a"; // Replaces <email> with <a> tag } } }
Pomocnicy tagów używają konwencji nazewnictwa, która jest przeznaczona dla elementów nazwy klasy głównej (minus część TagHelper nazwy klasy). W tym przykładzie główna nazwa elementu EmailTagHelper to adres e-mail, więc
<email>
tag będzie przeznaczony dla użytkownika. Ta konwencja nazewnictwa powinna działać dla większości pomocników tagów. Później pokażę, jak ją zastąpić.Klasa
EmailTagHelper
pochodzi z klasyTagHelper
. KlasaTagHelper
udostępnia metody i właściwości do pisania pomocników tagów.Przesłonięć
Process
metodę steruje tym, co robi pomocnik tagu podczas wykonywania. KlasaTagHelper
udostępnia również wersję asynchroniczną (ProcessAsync
) z tymi samymi parametrami.Parametr kontekstu do
Process
(iProcessAsync
) zawiera informacje skojarzone z wykonaniem bieżącego tagu HTML.Parametr wyjściowy do
Process
(iProcessAsync
) zawiera stanowy element HTML reprezentatywny dla oryginalnego źródła używanego do generowania tagu HTML i zawartości.Nasza nazwa klasy ma sufiks TagHelper, który nie jest wymagany, ale jest uważany za konwencję najlepszych rozwiązań. Klasę można zadeklarować jako:
public class Email : TagHelper
Aby udostępnić klasę
EmailTagHelper
wszystkim naszym Razor widokom, dodaj dyrektywęaddTagHelper
doViews/_ViewImports.cshtml
pliku:@using AuthoringTagHelpers @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers @addTagHelper *, AuthoringTagHelpers
Powyższy kod używa składni symboli wieloznacznych, aby określić wszystkie pomocniki tagów w naszym zestawie będą dostępne. Pierwszy ciąg po
@addTagHelper
określa pomocnik tagów do załadowania (użyj "*" dla wszystkich pomocników tagów), a drugi ciąg "AuthoringTagHelpers" określa zestaw, w których znajduje się pomocnik tagu. Należy również pamiętać, że drugi wiersz wprowadza pomocników tagów ASP.NET Core MVC przy użyciu składni symboli wieloznacznych (te pomocniki zostały omówione w temacie Wprowadzenie do pomocników tagów).@addTagHelper
Jest to dyrektywa, która sprawia, że pomocnik tagów Razor jest dostępny dla widoku. Alternatywnie można podać w pełni kwalifikowaną nazwę (FQN) pomocnika tagu, jak pokazano poniżej:
@using AuthoringTagHelpers
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@addTagHelper AuthoringTagHelpers.TagHelpers.EmailTagHelper, AuthoringTagHelpers
Aby dodać pomocnika tagów do widoku przy użyciu nazwy FQN, najpierw dodaj nazwę FQN (AuthoringTagHelpers.TagHelpers.EmailTagHelper
), a następnie nazwę zestawu (AuthoringTagHelpers, niekoniecznie namespace
). Większość deweloperów woli używać składni symboli wieloznacznych. Wprowadzenie do pomocników tagów zawiera szczegółowe informacje na temat dodawania, usuwania, hierarchii i składni symboli wieloznacznych.
Zaktualizuj znaczniki w
Views/Home/Contact.cshtml
pliku, wykonując następujące zmiany:@{ ViewData["Title"] = "Contact"; } <h2>@ViewData["Title"].</h2> <h3>@ViewData["Message"]</h3> <address> One Microsoft Way<br /> Redmond, WA 98052<br /> <abbr title="Phone">P:</abbr> 425.555.0100 </address> <address> <strong>Support:</strong><email>Support</email><br /> <strong>Marketing:</strong><email>Marketing</email> </address>
Uruchom aplikację i użyj ulubionej przeglądarki, aby wyświetlić źródło HTML, aby sprawdzić, czy tagi poczty e-mail zostały zastąpione znacznikami zakotwiczenia (na przykład
<a>Support</a>
). Obsługa i marketing są renderowane jako linki, ale nie mają atrybutu umożliwiającegohref
ich działanie. Naprawimy to w następnej sekcji.
SetAttribute i SetContent
W tej sekcji zaktualizujemy EmailTagHelper
element , aby utworzyć prawidłowy tag kotwicy dla wiadomości e-mail. Zaktualizujemy je, aby pobrać informacje z Razor widoku (w postaci atrybutu mail-to
) i użyć ich podczas generowania kotwicy.
Zaktualizuj klasę EmailTagHelper
przy użyciu następujących elementów:
public class EmailTagHelper : TagHelper
{
private const string EmailDomain = "contoso.com";
// Can be passed via <email mail-to="..." />.
// PascalCase gets translated into kebab-case.
public string MailTo { get; set; }
public override void Process(TagHelperContext context, TagHelperOutput output)
{
output.TagName = "a"; // Replaces <email> with <a> tag
var address = MailTo + "@" + EmailDomain;
output.Attributes.SetAttribute("href", "mailto:" + address);
output.Content.SetContent(address);
}
}
Pascal-cased klasy i nazwy właściwości pomocników tagów są tłumaczone na ich przypadek kebab. W związku z tym, aby użyć atrybutu
MailTo
, należy użyć<email mail-to="value"/>
odpowiednika.Ostatni wiersz ustawia ukończoną zawartość dla naszego pomocnika tagów minimalnej funkcjonalności.
Wyróżniony wiersz przedstawia składnię dodawania atrybutów:
public override void Process(TagHelperContext context, TagHelperOutput output)
{
output.TagName = "a"; // Replaces <email> with <a> tag
var address = MailTo + "@" + EmailDomain;
output.Attributes.SetAttribute("href", "mailto:" + address);
output.Content.SetContent(address);
}
To podejście działa dla atrybutu "href", o ile nie istnieje obecnie w kolekcji atrybutów. Możesz również użyć output.Attributes.Add
metody , aby dodać atrybut pomocnika tagu na końcu kolekcji atrybutów tagu.
Zaktualizuj znaczniki w
Views/Home/Contact.cshtml
pliku, wykonując następujące zmiany:@{ ViewData["Title"] = "Contact Copy"; } <h2>@ViewData["Title"].</h2> <h3>@ViewData["Message"]</h3> <address> One Microsoft Way Copy Version <br /> Redmond, WA 98052-6399<br /> <abbr title="Phone">P:</abbr> 425.555.0100 </address> <address> <strong>Support:</strong><email mail-to="Support"></email><br /> <strong>Marketing:</strong><email mail-to="Marketing"></email> </address>
Uruchom aplikację i sprawdź, czy generuje poprawne linki.
Uwaga
Jeśli chcesz napisać tag wiadomości e-mail samodzielnie zamykający (<email mail-to="Rick" />
), ostateczne dane wyjściowe będą również zamykane samodzielnie. Aby umożliwić pisanie tagu tylko za pomocą tagu startowego (<email mail-to="Rick">
), należy oznaczyć klasę następującymi elementami:
[HtmlTargetElement("email", TagStructure = TagStructure.WithoutEndTag)]
public class EmailVoidTagHelper : TagHelper
{
private const string EmailDomain = "contoso.com";
// Code removed for brevity
W przypadku pomocnika samodzielnego tagu wiadomości e-mail dane wyjściowe to <a href="mailto:Rick@contoso.com" />
. Tagi zakotwiczenia samodzielnego nie są prawidłowym kodem HTML, więc nie chcesz ich tworzyć, ale warto utworzyć pomocnika tagów, który jest zamykający. Pomocnicy tagów ustawiają typ TagMode
właściwości po odczytaniu tagu.
Możesz również zamapować inną nazwę atrybutu na właściwość przy użyciu atrybutu [HtmlAttributeName]
.
Aby zamapować atrybut o nazwie recipient
na MailTo
właściwość:
[HtmlAttributeName("recipient")]
public string? MailTo { get; set; }
Pomocnik tagu dla atrybutu recipient
:
<email recipient="…"/>
Processasync
W tej sekcji napiszemy asynchroniczną pomocnik poczty e-mail.
Zastąp klasę
EmailTagHelper
następującym kodem:public class EmailTagHelper : TagHelper { private const string EmailDomain = "contoso.com"; public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output) { output.TagName = "a"; // Replaces <email> with <a> tag var content = await output.GetChildContentAsync(); var target = content.GetContent() + "@" + EmailDomain; output.Attributes.SetAttribute("href", "mailto:" + target); output.Content.SetContent(target); } }
Uwagi:
Ta wersja używa metody asynchronicznej
ProcessAsync
. AsynchronicznyGetChildContentAsync
zwraca elementTask
zawierający elementTagHelperContent
.Użyj parametru ,
output
aby uzyskać zawartość elementu HTML.
Wprowadź następującą zmianę w
Views/Home/Contact.cshtml
pliku, aby pomocnik tagu mógł uzyskać docelową wiadomość e-mail.@{ ViewData["Title"] = "Contact"; } <h2>@ViewData["Title"].</h2> <h3>@ViewData["Message"]</h3> <address> One Microsoft Way<br /> Redmond, WA 98052<br /> <abbr title="Phone">P:</abbr> 425.555.0100 </address> <address> <strong>Support:</strong><email>Support</email><br /> <strong>Marketing:</strong><email>Marketing</email> </address>
Uruchom aplikację i sprawdź, czy generuje prawidłowe linki e-mail.
RemoveAll, PreContent.SetHtmlContent i PostContent.SetHtmlContent
Dodaj następującą
BoldTagHelper
klasę do folderu TagHelpers .using Microsoft.AspNetCore.Razor.TagHelpers; namespace AuthoringTagHelpers.TagHelpers { [HtmlTargetElement(Attributes = "bold")] public class BoldTagHelper : TagHelper { public override void Process(TagHelperContext context, TagHelperOutput output) { output.Attributes.RemoveAll("bold"); output.PreContent.SetHtmlContent("<strong>"); output.PostContent.SetHtmlContent("</strong>"); } } }
Atrybut
[HtmlTargetElement]
przekazuje parametr atrybutu, który określa, że dowolny element HTML zawierający atrybut HTML o nazwie "bold" będzie zgodny, aProcess
metoda zastąpienia w klasie zostanie uruchomiona. W naszym przykładzieProcess
metoda usuwa atrybut "bold" (pogrubienie) i otacza element zawierający znaczniki .<strong></strong>
Ponieważ nie chcesz zastępować istniejącej zawartości tagu, musisz napisać tag
PreContent.SetHtmlContent
otwierający<strong>
metodą i tag zamykający</strong>
metodąPostContent.SetHtmlContent
.
Zmodyfikuj widok tak
About.cshtml
, aby zawierał wartość atrybutubold
. Ukończony kod jest pokazany poniżej.@{ ViewData["Title"] = "About"; } <h2>@ViewData["Title"].</h2> <h3>@ViewData["Message"]</h3> <p bold>Use this area to provide additional information.</p> <bold> Is this bold?</bold>
Uruchom aplikację. Możesz użyć ulubionej przeglądarki, aby sprawdzić źródło i zweryfikować znaczniki.
Powyższy
[HtmlTargetElement]
atrybut dotyczy tylko znaczników HTML, które udostępniają nazwę atrybutu "bold". Element<bold>
nie został zmodyfikowany przez pomocnika tagów.Oznacz jako komentarz wiersz atrybutu
[HtmlTargetElement]
i domyślnie będzie to oznaczać tagi określania wartości docelowej<bold>
, czyli znaczniki HTML formularza<bold>
. Pamiętaj, że domyślna konwencja nazewnictwa będzie zgodna z nazwą klasy BoldTagHelper do<bold>
tagów.Uruchom aplikację i sprawdź,
<bold>
czy tag jest przetwarzany przez pomocnika tagów.
Dekorowanie klasy z wieloma [HtmlTargetElement]
atrybutami powoduje logiczne OR obiektów docelowych. Na przykład użycie poniższego kodu spowoduje dopasowanie pogrubionego tagu lub atrybutu pogrubionego.
[HtmlTargetElement("bold")]
[HtmlTargetElement(Attributes = "bold")]
public class BoldTagHelper : TagHelper
{
public override void Process(TagHelperContext context, TagHelperOutput output)
{
output.Attributes.RemoveAll("bold");
output.PreContent.SetHtmlContent("<strong>");
output.PostContent.SetHtmlContent("</strong>");
}
}
Po dodaniu wielu atrybutów do tej samej instrukcji środowisko uruchomieniowe traktuje je jako logiczne i. Na przykład w poniższym kodzie element HTML musi mieć nazwę "bold" z atrybutem o nazwie "bold" (<bold bold />
), aby był zgodny.
[HtmlTargetElement("bold", Attributes = "bold")]
Możesz również użyć elementu [HtmlTargetElement]
, aby zmienić nazwę elementu docelowego. Jeśli na przykład chcesz użyć tagów BoldTagHelper
docelowych <MyBold>
, użyj następującego atrybutu:
[HtmlTargetElement("MyBold")]
Przekazywanie modelu do pomocnika tagów
Dodaj folder Models.
Dodaj następującą
WebsiteContext
klasę do folderu Models :using System; namespace AuthoringTagHelpers.Models { public class WebsiteContext { public Version Version { get; set; } public int CopyrightYear { get; set; } public bool Approved { get; set; } public int TagsToShow { get; set; } } }
Dodaj następującą
WebsiteInformationTagHelper
klasę do folderu TagHelpers .using System; using AuthoringTagHelpers.Models; using Microsoft.AspNetCore.Razor.TagHelpers; namespace AuthoringTagHelpers.TagHelpers { public class WebsiteInformationTagHelper : TagHelper { public WebsiteContext Info { get; set; } public override void Process(TagHelperContext context, TagHelperOutput output) { output.TagName = "section"; output.Content.SetHtmlContent( $@"<ul><li><strong>Version:</strong> {Info.Version}</li> <li><strong>Copyright Year:</strong> {Info.CopyrightYear}</li> <li><strong>Approved:</strong> {Info.Approved}</li> <li><strong>Number of tags to show:</strong> {Info.TagsToShow}</li></ul>"); output.TagMode = TagMode.StartTagAndEndTag; } } }
Jak wspomniano wcześniej, pomocnicy tagów tłumaczą pascal-cased nazwy klas i właściwości języka C# dla pomocników tagów w przypadku kebab. W związku z tym, aby użyć elementu
WebsiteInformationTagHelper
w Razorpliku , napiszesz .<website-information />
Nie identyfikujesz jawnie elementu docelowego za pomocą atrybutu
[HtmlTargetElement]
, więc wartość domyślna będzie przeznaczonawebsite-information
. Jeśli zastosowano następujący atrybut (zwróć uwagę, że nie jest to przypadek kebab, ale pasuje do nazwy klasy):
[HtmlTargetElement("WebsiteInformation")]
Tag
<website-information />
przypadku kebab nie pasuje. Jeśli chcesz użyć atrybutu[HtmlTargetElement]
, użyj przypadku kebab, jak pokazano poniżej:[HtmlTargetElement("Website-Information")]
Elementy, które się zamykają, nie mają zawartości. W tym przykładzie Razor adiustacja będzie używać tagu samo zamykającego, ale pomocnik tagu utworzy element sekcji (który nie zamyka się samodzielnie i piszesz zawartość wewnątrz
section
elementu). W związku z tym należy ustawić wartośćTagMode
na wartość , abyStartTagAndEndTag
zapisywać dane wyjściowe. Alternatywnie możesz oznaczyć jako komentarz ustawienieTagMode
wiersza i zapisać znaczniki z tagiem zamykającym. (Przykładowy znacznik jest udostępniany w dalszej części tego samouczka).Znak
$
(dolara) w następującym wierszu używa ciągu interpolowanego:
$@"<ul><li><strong>Version:</strong> {Info.Version}</li>
Dodaj następujący znacznik do
About.cshtml
widoku. Wyróżniony znacznik wyświetla informacje o witrynie internetowej.@using AuthoringTagHelpers.Models @{ ViewData["Title"] = "About"; WebsiteContext webContext = new WebsiteContext { Version = new Version(1, 3), CopyrightYear = 1638, Approved = true, TagsToShow = 131 }; } <h2>@ViewData["Title"].</h2> <h3>@ViewData["Message"]</h3> <p bold>Use this area to provide additional information.</p> <bold> Is this bold?</bold> <h3> web site info </h3> <website-information info="webContext" />
Uwaga
W adiustacji Razor pokazanej poniżej:
<website-information info="webContext" />
Razor wie, że
info
atrybut jest klasą, a nie ciągiem i chcesz napisać kod języka C#. Każdy atrybut pomocnika tagów@
innych niż ciąg powinien być zapisywany bez znaku .Uruchom aplikację i przejdź do widoku Informacje, aby wyświetlić informacje o witrynie internetowej.
Uwaga
Możesz użyć następującego znacznika z tagiem zamykającym i usunąć wiersz z
TagMode.StartTagAndEndTag
w pomocniku tagu:<website-information info="webContext" > </website-information>
Pomocnik tagu warunku
Pomocnik tagu warunku renderuje dane wyjściowe po przekazaniu wartości true.
Dodaj następującą
ConditionTagHelper
klasę do folderu TagHelpers .using Microsoft.AspNetCore.Razor.TagHelpers; namespace AuthoringTagHelpers.TagHelpers { [HtmlTargetElement(Attributes = nameof(Condition))] public class ConditionTagHelper : TagHelper { public bool Condition { get; set; } public override void Process(TagHelperContext context, TagHelperOutput output) { if (!Condition) { output.SuppressOutput(); } } } }
Zastąp zawartość
Views/Home/Index.cshtml
pliku następującym znacznikiem:@using AuthoringTagHelpers.Models @model WebsiteContext @{ ViewData["Title"] = "Home Page"; } <div> <h3>Information about our website (outdated):</h3> <Website-InforMation info="Model" /> <div condition="Model.Approved"> <p> This website has <strong surround="em">@Model.Approved</strong> been approved yet. Visit www.contoso.com for more information. </p> </div> </div>
Zastąp metodę
Index
w kontrolerzeHome
następującym kodem:public IActionResult Index(bool approved = false) { return View(new WebsiteContext { Approved = approved, CopyrightYear = 2015, Version = new Version(1, 3, 3, 7), TagsToShow = 20 }); }
Uruchom aplikację i przejdź do strony głównej. Znaczniki w warunkowym
div
nie zostaną renderowane. Dołącz ciąg?approved=true
zapytania do adresu URL (na przykładhttp://localhost:1235/Home/Index?approved=true
).approved
jest ustawiona na wartość true, a zostanie wyświetlony znacznik warunkowy.
Uwaga
Użyj operatora nameof, aby określić atrybut docelowy, zamiast określać ciąg tak jak w przypadku pomocnika pogrubienia tagów:
[HtmlTargetElement(Attributes = nameof(Condition))]
// [HtmlTargetElement(Attributes = "condition")]
public class ConditionTagHelper : TagHelper
{
public bool Condition { get; set; }
public override void Process(TagHelperContext context, TagHelperOutput output)
{
if (!Condition)
{
output.SuppressOutput();
}
}
}
Operator nameof będzie chronić kod, jeśli kiedykolwiek zostanie refaktoryzowany (możemy zmienić nazwę na RedCondition
).
Unikanie konfliktów pomocnika tagów
W tej sekcji napiszesz parę pomocników tagów automatycznego łączenia. Pierwszy zastąpi znaczniki zawierające adres URL rozpoczynający się od HTTP do tagu kotwicy HTML zawierającego ten sam adres URL (i w ten sposób zwraca link do adresu URL). Drugi zrobi to samo dla adresu URL rozpoczynającego się od WWW.
Ponieważ te dwie pomocniki są ściśle powiązane i można je refaktoryzują w przyszłości, zachowamy je w tym samym pliku.
Dodaj następującą
AutoLinkerHttpTagHelper
klasę do folderu TagHelpers .[HtmlTargetElement("p")] public class AutoLinkerHttpTagHelper : TagHelper { public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output) { var childContent = await output.GetChildContentAsync(); // Find Urls in the content and replace them with their anchor tag equivalent. output.Content.SetHtmlContent(Regex.Replace( childContent.GetContent(), @"\b(?:https?://)(\S+)\b", "<a target=\"_blank\" href=\"$0\">$0</a>")); // http link version} } }
Uwaga
Klasa jest przeznaczona
AutoLinkerHttpTagHelper
dlap
elementów docelowych i używa wyrażenia regularnego do utworzenia kotwicy.Dodaj następujący znacznik na końcu
Views/Home/Contact.cshtml
pliku:@{ ViewData["Title"] = "Contact"; } <h2>@ViewData["Title"].</h2> <h3>@ViewData["Message"]</h3> <address> One Microsoft Way<br /> Redmond, WA 98052<br /> <abbr title="Phone">P:</abbr> 425.555.0100 </address> <address> <strong>Support:</strong><email>Support</email><br /> <strong>Marketing:</strong><email>Marketing</email> </address> <p>Visit us at http://docs.asp.net or at www.microsoft.com</p>
Uruchom aplikację i sprawdź, czy pomocnik tagu poprawnie renderuje kotwicę.
Zaktualizuj klasę tak
AutoLinker
, aby zawierałaAutoLinkerWwwTagHelper
tekst www przekonwertowany na tag kotwicy zawierający również oryginalny tekst www. Zaktualizowany kod został wyróżniony poniżej:[HtmlTargetElement("p")] public class AutoLinkerHttpTagHelper : TagHelper { public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output) { var childContent = await output.GetChildContentAsync(); // Find Urls in the content and replace them with their anchor tag equivalent. output.Content.SetHtmlContent(Regex.Replace( childContent.GetContent(), @"\b(?:https?://)(\S+)\b", "<a target=\"_blank\" href=\"$0\">$0</a>")); // http link version} } } [HtmlTargetElement("p")] public class AutoLinkerWwwTagHelper : TagHelper { public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output) { var childContent = await output.GetChildContentAsync(); // Find Urls in the content and replace them with their anchor tag equivalent. output.Content.SetHtmlContent(Regex.Replace( childContent.GetContent(), @"\b(www\.)(\S+)\b", "<a target=\"_blank\" href=\"http://$0\">$0</a>")); // www version } } }
Uruchom aplikację. Zwróć uwagę, że tekst www jest renderowany jako link, ale tekst HTTP nie jest. Jeśli umieścisz punkt przerwania w obu klasach, zobaczysz, że klasa pomocnika tagów HTTP jest uruchamiana jako pierwsza. Problem polega na tym, że dane wyjściowe pomocnika tagów są buforowane, a gdy pomocnik tagów WWW jest uruchamiany, zastępuje buforowane dane wyjściowe z pomocnika tagów HTTP. W dalszej części samouczka zobaczymy, jak kontrolować kolejność uruchamiania pomocników tagów. Naprawimy kod przy użyciu następujących elementów:
public class AutoLinkerHttpTagHelper : TagHelper { public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output) { var childContent = output.Content.IsModified ? output.Content.GetContent() : (await output.GetChildContentAsync()).GetContent(); // Find Urls in the content and replace them with their anchor tag equivalent. output.Content.SetHtmlContent(Regex.Replace( childContent, @"\b(?:https?://)(\S+)\b", "<a target=\"_blank\" href=\"$0\">$0</a>")); // http link version} } } [HtmlTargetElement("p")] public class AutoLinkerWwwTagHelper : TagHelper { public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output) { var childContent = output.Content.IsModified ? output.Content.GetContent() : (await output.GetChildContentAsync()).GetContent(); // Find Urls in the content and replace them with their anchor tag equivalent. output.Content.SetHtmlContent(Regex.Replace( childContent, @"\b(www\.)(\S+)\b", "<a target=\"_blank\" href=\"http://$0\">$0</a>")); // www version } }
Uwaga
W pierwszej edycji pomocników tagów automatycznego łączenia uzyskasz zawartość obiektu docelowego z następującym kodem:
var childContent = await output.GetChildContentAsync();
Oznacza to, że wywołujesz
GetChildContentAsync
metodę przy użyciuTagHelperOutput
metody przekazanejProcessAsync
. Jak wspomniano wcześniej, ponieważ dane wyjściowe są buforowane, ostatni pomocnik tagu do uruchomienia wygrywa. Rozwiązano ten problem z następującym kodem:var childContent = output.Content.IsModified ? output.Content.GetContent() : (await output.GetChildContentAsync()).GetContent();
Powyższy kod sprawdza, czy zawartość została zmodyfikowana, a jeśli została ona zmodyfikowana, pobiera zawartość z buforu wyjściowego.
Uruchom aplikację i sprawdź, czy dwa linki działają zgodnie z oczekiwaniami. Chociaż może się wydawać, że nasz pomocnik tagów automatycznego konsolidatora jest poprawny i kompletny, ma subtelny problem. Jeśli pomocnik tagów WWW jest uruchamiany jako pierwszy, linki www nie będą poprawne. Zaktualizuj kod, dodając przeciążenie,
Order
aby kontrolować kolejność uruchamiania tagu. WłaściwośćOrder
określa kolejność wykonywania względem innych pomocników tagów przeznaczonych dla tego samego elementu. Domyślna wartość zamówienia to zero, a wystąpienia o niższych wartościach są wykonywane jako pierwsze.public class AutoLinkerHttpTagHelper : TagHelper { // This filter must run before the AutoLinkerWwwTagHelper as it searches and replaces http and // the AutoLinkerWwwTagHelper adds http to the markup. public override int Order { get { return int.MinValue; } }
Powyższy kod gwarantuje, że pomocnik tagów HTTP jest uruchamiany przed pomocnikem tagów WWW. Zmień
Order
wartość naMaxValue
i sprawdź, czy znacznik wygenerowany dla tagu WWW jest niepoprawny.
Inspekcja i pobieranie zawartości podrzędnej
Pomocnicy tagów udostępniają kilka właściwości do pobierania zawartości.
- Wynik
GetChildContentAsync
można dołączyć dooutput.Content
. - Możesz sprawdzić wynik polecenia za pomocą
GetContent
poleceniaGetChildContentAsync
. - Jeśli zmodyfikujesz
output.Content
element , treść narzędzia TagHelper nie zostanie wykonana ani renderowana, chyba że wywołaszGetChildContentAsync
metodę tak jak w naszym przykładzie automatycznego konsolidatora:
public class AutoLinkerHttpTagHelper : TagHelper
{
public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
{
var childContent = output.Content.IsModified ? output.Content.GetContent() :
(await output.GetChildContentAsync()).GetContent();
// Find Urls in the content and replace them with their anchor tag equivalent.
output.Content.SetHtmlContent(Regex.Replace(
childContent,
@"\b(?:https?://)(\S+)\b",
"<a target=\"_blank\" href=\"$0\">$0</a>")); // http link version}
}
}
- Wiele wywołań zwraca
GetChildContentAsync
tę samą wartość i nie wykonujeTagHelper
ponownie treści, chyba że przekazano parametr false wskazujący, że nie używasz buforowanego wyniku.
Ładowanie zminimalizowanego widoku częściowego TagHelper
W środowiskach produkcyjnych wydajność można poprawić przez ładowanie minyfikowanych widoków częściowych. Aby skorzystać z z minyfikowanego widoku częściowego w środowisku produkcyjnym:
- Utwórz/skonfiguruj proces wstępnej kompilacji, który minifiesuje widoki częściowe.
- Użyj poniższego kodu, aby załadować minyfikowane częściowe widoki w środowiskach nieprogramowania.
public class MinifiedVersionPartialTagHelper : PartialTagHelper
{
public MinifiedVersionPartialTagHelper(ICompositeViewEngine viewEngine,
IViewBufferScope viewBufferScope)
: base(viewEngine, viewBufferScope)
{
}
public override Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
{
// Append ".min" to load the minified partial view.
if (!IsDevelopment())
{
Name += ".min";
}
return base.ProcessAsync(context, output);
}
private bool IsDevelopment()
{
return Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")
== EnvironmentName.Development;
}
}
Opinia
https://aka.ms/ContentUserFeedback.
Dostępne już wkrótce: W 2024 r. będziemy stopniowo wycofywać zgłoszenia z serwisu GitHub jako mechanizm przesyłania opinii na temat zawartości i zastępować go nowym systemem opinii. Aby uzyskać więcej informacji, sprawdź:Prześlij i wyświetl opinię dla