Creare helper tag in ASP.NET Core
Visualizzare o scaricare il codice di esempio (procedura per il download)
Guida introduttiva agli helper tag
Questa esercitazione rappresenta un'introduzione alla programmazione di helper tag. Introduzione agli helper tag descrive i vantaggi offerti dagli helper tag.
Un helper tag è una classe che implementa l'interfaccia ITagHelper
. Quando si crea un helper tag, tuttavia, in genere lo si deriva da TagHelper
. In questo modo si ottiene l'accesso al metodo Process
.
Creare un nuovo progetto ASP.NET Core denominato AuthoringTagHelpers. Per questo progetto non sarà necessaria l'autenticazione.
Creare una cartella che contenga gli helper tag denominata TagHelpers. La cartella TagHelpersnon è obbligatoria, ma rappresenta una convenzione sensata. È ora possibile iniziare a scrivere alcuni helper tag semplici.
Un helper tag piccolissimo
In questa sezione verrà scritto un helper tag che aggiorna un tag di posta elettronica. Ad esempio:
<email>Support</email>
Il server userà l'helper tag di posta elettronica creato per convertire il markup nel codice seguente:
<a href="mailto:Support@contoso.com">Support@contoso.com</a>
In altre parole, un tag di ancoraggio che dà come risultato un collegamento di posta elettronica. È necessario eseguire questa operazione se si sta scrivendo un motore di blog e si vuole inviare posta elettronica di marketing o di supporto ad altri contatti, tutti nello stesso dominio.
Aggiungere la classe
EmailTagHelper
seguente alla cartella 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 } } }
Gli helper tag usano una convenzione di denominazione che interessa gli elementi del nome della classe di base (meno la parte TagHelper del nome della classe). In questo esempio il nome radice di EmailTagHelper è email, pertanto il tag
<email>
viene considerato come destinazione. Questa convenzione di denominazione dovrebbe funzionare per la maggior parte degli helper tag. Più avanti verrà illustrato come eseguirne l'override.La classe
EmailTagHelper
deriva daTagHelper
. La classeTagHelper
mette a disposizione metodi e proprietà per la scrittura di helper tag.Il metodo
Process
sottoposto a override controlla ciò che l'helper tag fa quando viene eseguito. La classeTagHelper
fornisce anche una versione asincrona (ProcessAsync
) con gli stessi parametri.Il parametro context di
Process
(eProcessAsync
) contiene informazioni associate all'esecuzione del tag HTML corrente.Il parametro output di
Process
(eProcessAsync
) contiene un elemento HTML con stato rappresentativo dell'origine originale usato per generare un tag e del contenuto HTML.Il nome della classe usata ha il suffisso TagHelper, che non è obbligatorio, ma il cui uso è considerato una convenzione basata su procedure consigliate. È possibile dichiarare la classe come:
public class Email : TagHelper
Per rendere la
EmailTagHelper
classe disponibile per tutte le Razor visualizzazioni, aggiungere laaddTagHelper
direttiva alViews/_ViewImports.cshtml
file :@using AuthoringTagHelpers @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers @addTagHelper *, AuthoringTagHelpers
Il codice qui sopra usa la sintassi con caratteri jolly per specificare che tutti gli helper tag in questo assembly saranno disponibili. La prima stringa dopo
@addTagHelper
specifica l'helper tag da caricare (usare "*" per indicare tutti gli helper tag), e la seconda stringa "AuthoringTagHelpers" specifica l'assembly in cui si trova l'helper tag. Si noti anche che la seconda riga inserisce gli helper tag MVC core ASP.NET usando la sintassi con caratteri jolly (tali helper sono descritti in Introduzione agli helper tag). Si tratta della@addTagHelper
direttiva che rende disponibile l'helper tag per la Razor visualizzazione. In alternativa, è possibile specificare il nome completo dell'helper tag, come illustrato di seguito:
@using AuthoringTagHelpers
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@addTagHelper AuthoringTagHelpers.TagHelpers.EmailTagHelper, AuthoringTagHelpers
Per aggiungere un helper tag a una visualizzazione usando un nome completo, aggiungere prima il nome completo (AuthoringTagHelpers.TagHelpers.EmailTagHelper
) e quindi il nome dell'assembly (AuthoringTagHelpers, non necessariamente namespace
). La maggior parte degli sviluppatori preferisce usare la sintassi con caratteri jolly. Introduzione agli helper tag descrive in dettaglio la sintassi di aggiunta, rimozione, gerarchia degli helper tag, nonché la sintassi con caratteri jolly.
Aggiornare il markup nel
Views/Home/Contact.cshtml
file con queste modifiche:@{ 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>
Eseguire l'app e usare il browser preferito per visualizzare l'origine HTML e verificare che i tag di posta elettronica siano stati sostituiti dal markup di ancoraggio, ad esempio,
<a>Support</a>
. Support e Marketing sono visualizzati come collegamenti, ma non hanno un attributohref
che li renda funzionali. Questo problema verrà corretto nella prossima sezione.
SetAttribute e SetContent
In questa sezione la classe EmailTagHelper
verrà aggiornata in modo che crei un tag di ancoraggio valido per la posta elettronica. Lo aggiorneremo per acquisire informazioni da una Razor vista (sotto forma di mail-to
attributo) e usarle per generare l'ancoraggio.
Aggiornare la classe EmailTagHelper
con il codice seguente:
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);
}
}
I nomi della classe e delle proprietà per gli helper tag, scritti secondo la convenzione Pascal, vengono convertiti nel formato kebab case corrispondente. Per usare l'attributo
MailTo
, pertanto, si userà l'equivalente<email mail-to="value"/>
.L'ultima riga imposta il contenuto completato per l'helper tag dalle minime funzioni.
La riga evidenziata illustra la sintassi per l'aggiunta di attributi:
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);
}
Questo approccio funziona per l'attributo "href" a condizione che non esista nella raccolta di attributi. È anche possibile usare il metodo output.Attributes.Add
per aggiungere un attributo di helper tag alla fine della raccolta di attributi di tag.
Aggiornare il markup nel
Views/Home/Contact.cshtml
file con queste modifiche:@{ 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>
Eseguire l'app e verificare che generi collegamenti corretti.
Nota
Se si scrive il tag di posta elettronica a chiusura automatica (<email mail-to="Rick" />
), anche l'output finale è a chiusura automatica. Per abilitare la possibilità di scrivere il tag con solo un tag iniziale (<email mail-to="Rick">
) è necessario contrassegnare la classe con quanto segue:
[HtmlTargetElement("email", TagStructure = TagStructure.WithoutEndTag)]
public class EmailVoidTagHelper : TagHelper
{
private const string EmailDomain = "contoso.com";
// Code removed for brevity
Con un helper tag di posta elettronica a chiusura automatica, l'output è <a href="mailto:Rick@contoso.com" />
. I tag di ancoraggio a chiusura automatica non costituiscono codice HTML valido ed è quindi necessario evitare di crearli, ma può essere necessario creare un helper tag a chiusura automatica. Gli helper tag impostano il tipo della proprietà TagMode
dopo la lettura di un tag.
È anche possibile eseguire il mapping di un nome di attributo diverso a una proprietà usando l'attributo [HtmlAttributeName]
.
Per eseguire il mapping di un attributo denominato recipient
alla MailTo
proprietà :
[HtmlAttributeName("recipient")]
public string? MailTo { get; set; }
Helper tag per l'attributo recipient
:
<email recipient="…"/>
ProcessAsync
In questa sezione verrà scritto un helper di posta elettronica asincrono.
Sostituire la classe
EmailTagHelper
con il codice seguente: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); } }
Note:
Questa versione usa il metodo
ProcessAsync
asincrono.GetChildContentAsync
asincrono restituisce unTask
contenenteTagHelperContent
.Usare il parametro
output
per ottenere il contenuto dell'elemento HTML.
Apportare la modifica seguente al
Views/Home/Contact.cshtml
file in modo che l'helper tag possa ottenere il messaggio di posta elettronica di destinazione.@{ 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>
Eseguire l'app e verificare che generi collegamenti di posta elettronica validi.
RemoveAll, PreContent.SetHtmlContent e PostContent.SetHtmlContent
Aggiungere la classe
BoldTagHelper
seguente alla cartella 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>"); } } }
L'attributo
[HtmlTargetElement]
passa un parametro di attributo che specifica che qualsiasi elemento HTML che contenga un attributo HTML denominato "bold" corrisponderà e che quindi verrà eseguito il metodo di overrideProcess
nella classe. Nell'esempio, il metodoProcess
rimuove l'attributo "bold" e racchiude il markup tra<strong></strong>
.Dato che non si deve sostituire il contenuto esistente del tag, è necessario scrivere il tag
<strong>
di apertura con il metodoPreContent.SetHtmlContent
e il tag</strong>
di chiusura con il metodoPostContent.SetHtmlContent
.
Modificare la
About.cshtml
visualizzazione in modo che contenga un valore dibold
attributo. Il codice completo è illustrato di seguito.@{ 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>
Eseguire l'app. È possibile usare il browser preferito per controllare l'origine e verificare il markup.
L'attributo
[HtmlTargetElement]
qui sopra ha come destinazione solo il markup HTML che fornisce un nome di attributo corrispondente a "bold". L'elemento<bold>
non è stato modificato dall'helper tag.Impostare come commento la riga dell'attributo
[HtmlTargetElement]
. Per impostazione predefinita, userà quindi tag<bold>
, vale a dire il markup HTML nel formato<bold>
. Tenere presente che la convenzione di denominazione predefinita corrisponderà al nome della classe BoldTagHelper per i tag<bold>
.Eseguire l'applicazione e verificare che il tag
<bold>
venga elaborato dall'helper tag.
La decorazione di una classe con più attributi [HtmlTargetElement]
risulta in un OR logico delle destinazioni. Usando il codice riportato di seguito, ad esempio, un tag bold o un attributo bold corrisponderanno.
[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>");
}
}
Se si aggiungono più attributi alla stessa istruzione, il runtime li gestisce come AND logici. Nel codice riportato di seguito, ad esempio, perché corrisponda, un elemento HTML deve essere denominato "bold" con un attributo denominato "bold" (<bold bold />
).
[HtmlTargetElement("bold", Attributes = "bold")]
È anche possibile usare [HtmlTargetElement]
per modificare il nome dell'elemento di destinazione. Se ad esempio si vuole che BoldTagHelper
abbia come destinazione tag <MyBold>
, usare l'attributo seguente:
[HtmlTargetElement("MyBold")]
Passare un modello a un helper tag
Aggiungere una cartella Models.
Aggiungere la classe
WebsiteContext
seguente alla cartella 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; } } }
Aggiungere la classe
WebsiteInformationTagHelper
seguente alla cartella 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; } } }
Come affermato in precedenza, gli helper tag convertono i nomi delle relative classi e proprietà C#, definiti secondo la convenzione Pascal, in formato kebab case. Pertanto, per usare in
WebsiteInformationTagHelper
Razor, si scriverà<website-information />
.Non si sta identificando in modo esplicito l'elemento di destinazione con l'attributo
[HtmlTargetElement]
e quindi verrà considerato come destinazione il valore predefinito diwebsite-information
. Se è stato applicato l'attributo seguente (si noti che non è nel formato kebab case ma corrisponde al nome della classe):
[HtmlTargetElement("WebsiteInformation")]
Il tag nel formato kebab case
<website-information />
non corrisponde. Se si vuole usare l'attributo[HtmlTargetElement]
, è necessario usare il formato kebab case come illustrato di seguito:[HtmlTargetElement("Website-Information")]
Gli elementi a chiusura automatica non hanno contenuto. Per questo esempio, il Razor markup userà un tag di chiusura automatica, ma l'helper tag creerà un elemento di sezione (che non si chiude automaticamente e si sta scrivendo contenuto all'interno dell'elemento
section
). Per scrivere output, è pertanto necessario impostareTagMode
suStartTagAndEndTag
. In alternativa, è possibile impostare come commento la riga che impostaTagMode
e scrivere markup con un tag di chiusura. Del markup di esempio viene fornito più avanti in questa esercitazione.Il simbolo
$
(segno di dollaro) nella riga seguente usa una stringa interpolata:
$@"<ul><li><strong>Version:</strong> {Info.Version}</li>
Aggiungere il markup seguente alla
About.cshtml
visualizzazione. Il markup evidenziato visualizza le informazioni sul sito Web.@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" />
Nota
Razor Nel markup illustrato di seguito:
<website-information info="webContext" />
Razor sa che l'attributo
info
è una classe, non una stringa e si vuole scrivere codice C#. Qualsiasi attributo di helper tag non di tipo stringa deve essere scritto senza il carattere@
.Eseguire l'app e passare alla visualizzazione About per visualizzare le informazioni sul sito Web.
Nota
È possibile usare il markup seguente con un tag di chiusura e rimuovere la riga con
TagMode.StartTagAndEndTag
nell'helper tag:<website-information info="webContext" > </website-information>
Helper tag di condizione
L'helper tag di condizione esegue il rendering dell'output quando riceve un valore true.
Aggiungere la classe
ConditionTagHelper
seguente alla cartella 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(); } } } }
Sostituire il contenuto del
Views/Home/Index.cshtml
file con il markup seguente:@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>
Sostituire il metodo
Index
nel controllerHome
con il codice seguente:public IActionResult Index(bool approved = false) { return View(new WebsiteContext { Approved = approved, CopyrightYear = 2015, Version = new Version(1, 3, 3, 7), TagsToShow = 20 }); }
Eseguire l'app e passare alla home page. Non verrà eseguito il rendering del markup in
div
condizionale. Accodare la stringa di query?approved=true
all'URL (ad esempio,http://localhost:1235/Home/Index?approved=true
).approved
è impostato su true e il markup condizionale verrà visualizzato.
Nota
Usare l'operatore nameof per specificare l'attributo di destinazione, anziché specificare una stringa, come è stato fatto per l'helper tag bold:
[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();
}
}
}
L'operatore nameof proteggerà il codice nel caso venisse effettuato il refactoring (potrebbe essere necessario modificare il nome in RedCondition
).
Evitare conflitti di helper tag
In questa sezione verrà scritta una coppia di helper tag a collegamento automatico. Il primo sostituirà il markup contenente un URL che inizia con HTTP con un tag di ancoraggio HTML contenente lo stesso URL (e che quindi genera un collegamento all'URL). Il secondo eseguirà la stessa operazione per un URL che inizia con WWW.
Poiché questi due helper sono strettamente correlati e in futuro potrebbero essere sottoposti a refactoring, verranno mantenuti nello stesso file.
Aggiungere la classe
AutoLinkerHttpTagHelper
seguente alla cartella 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} } }
Nota
La classe
AutoLinkerHttpTagHelper
ha come destinazioni elementip
e usa Regex per creare l'ancoraggio.Aggiungere il markup seguente alla fine del
Views/Home/Contact.cshtml
file:@{ 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>
Eseguire l'app e verificare che l'helper tag esegua correttamente il rendering dell'ancoraggio.
Aggiornare la classe
AutoLinker
per includereAutoLinkerWwwTagHelper
che convertirà il testo www in un tag di ancoraggio contenente anch'esso il testo www originale. Il codice aggiornato è evidenziato di seguito:[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 } } }
Eseguire l'app. Si noti che il testo www è visualizzato come collegamento, ma il testo HTTP non lo è. Se si inserisce un punto di interruzione in entrambe le classi, è possibile notare che la classe helper tag HTTP viene eseguita per prima. Il problema è che l'output dell'helper tag viene memorizzato nella cache. Quando viene eseguito l'helper tag WWW, quest'ultimo sovrascrive l'output dell'helper tag HTTP memorizzato nella cache. Più avanti in questa esercitazione verrà illustrato come controllare l'ordine di esecuzione degli helper tag. È possibile correggere il problema con il codice seguente:
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 } }
Nota
Nella prima edizione degli helper tag a collegamento automatico, per ottenere il contenuto della destinazione è stato usato il codice seguente:
var childContent = await output.GetChildContentAsync();
In altre parole, si effettua una chiamata a
GetChildContentAsync
usandoTagHelperOutput
passato al metodoProcessAsync
. Come affermato in precedenza, poiché l'output viene memorizzato nella cache, l'ultimo helper eseguito prevale. Il problema è stato risolto con il codice seguente:var childContent = output.Content.IsModified ? output.Content.GetContent() : (await output.GetChildContentAsync()).GetContent();
Il codice precedente controlla se il contenuto è stato modificato e, in caso affermativo, ottiene il contenuto dal buffer di output.
Eseguire l'app e verificare che i due collegamenti funzionino come previsto. Può sembrare che l'helper tag a collegamento automatico sia corretto e completo, ma presenta un problema insidioso. Se l'helper tag WWW viene eseguito per primo, i collegamenti www non sono corretti. Aggiornare il codice aggiungendo l'overload
Order
per controllare l'ordine in cui viene eseguito il tag. La proprietàOrder
determina l'ordine di esecuzione rispetto agli altri helper tag che hanno come destinazione lo stesso elemento. Il valore dell'ordine predefinito è zero e le istanze con valori inferiori vengono eseguite per prime.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; } }
Il codice precedente assicura che l'helper tag HTTP venga eseguito prima dell'helper tag WWW. Modificare
Order
inMaxValue
e verificare che il markup generato per il tag WWW non è corretto.
Controllare e recuperare il contenuto figlio
Gli helper tag mettono a disposizione diverse proprietà per recuperare il contenuto.
- Il risultato di
GetChildContentAsync
può essere accodato aoutput.Content
. - È possibile controllare il risultato di
GetChildContentAsync
conGetContent
. - Se si modifica
output.Content
, il corpo di TagHelper viene eseguito, o ne viene eseguito il rendering, solo se si chiamaGetChildContentAsync
, come nell'esempio di helper tag a collegamento automatico:
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}
}
}
- Più chiamate al metodo
GetChildContentAsync
restituiscono lo stesso valore e rieseguono nuovamente il corpo diTagHelper
solo se viene passato un parametro false per indicare di non usare il risultato memorizzato nella cache.
TagHelper per caricare visualizzazioni parziali minimizzate
Negli ambienti di produzione le prestazioni possono essere migliorate caricando visualizzazioni parziali minimizzate. Per sfruttare i vantaggi della visualizzazione parziale minimizzata nell'ambiente di produzione:
- Creare/configurare un processo di pre-compilazione che minimizza visualizzazioni parziali.
- Usare il codice seguente per caricare le visualizzazioni parziali minimizzate in ambienti non di sviluppo.
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;
}
}
Commenti e suggerimenti
https://aka.ms/ContentUserFeedback.
Presto disponibile: Nel corso del 2024 verranno gradualmente disattivati i problemi di GitHub come meccanismo di feedback per il contenuto e ciò verrà sostituito con un nuovo sistema di feedback. Per altre informazioni, vedereInvia e visualizza il feedback per