原文:Authoring Tag Helpers
作者:Rick Anderson
翻譯:張海龍(jiechen)
校對:許登洋(Seay)
從 Tag Helper 講起
本篇教程是對 Tag Helper 編程作以介紹。 Tag Helpers 介紹 描述了 Tag Helper 的優勢。
Tag Helper 是任何實現 ITagHelper
接口的類(Class)。然而,當你編寫一個 Tag Helper,你通常是從 TagHelper
開始,這樣做讓你可以訪問 Process
方法。我們將介紹 TagHelper
方法和屬性,如同我們將在本教程使用它們的。
創建一個命名為 AuthoringTagHelpers 的新 ASP.NET Core 項目。對該項目你不需要添加身份驗證。
創建一個用來放置 Tag Helper 的 TagHelpers 文件夾。 TagHelpers 文件夾是 非 必需的,但它是一個合理的慣例。現在讓我們來開始編寫一些簡單的 Tag Helper。
編寫 email Tag Helper
這一節我們將寫一個 Tag Helper ,用來更新 email 標簽。例如:
<email>Support</email>
服務端將使用我們的 email Tag Helper 來生成以下標記:
<a href="mailto:Support@contoso.com">Support@contoso.com</a>
也就是,一個錨標簽轉為了一個 email 鏈接。如果你在寫一個博客引擎,並且需要它為市場、支持、其他聯系人發送郵件到相同的域,你可能想要這樣做。
1.添加下面的 EmailTagHelper
類到 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
}
}
}
說明:
- Tag helper 使用以目標元素名作為根類名(除去類名中 TagHelper 部分)的命名約定。在這個例子中, EmailTagHelper 的根名稱是 email ,因此
<email>
標簽將是目標標簽。這個命名約定適用於大多數 tag helper ,稍后我將展示如何對它重寫。 EmailTagHelper
類派生自TagHelper
。TagHelper
類提供了我們即將在本文探究的豐富的方法和屬性。- 重寫
Process
方法可以控制 Tag Helper 在執行過程中的行為。TagHelper
類同樣提供了相同參數的異步版本(ProcessAsync
)。 Process
(或ProcessAsync
)的上下文參數包含了與當前 HTML 標簽執行的相關信息。Process
(或ProcessAsync
)的輸出參數包含了用來生成 HTML 標簽和內容的源代碼的靜態 HTML 元素呈現。- 我們的類名后綴為 TagHelper ,是 非 必需的,但它被認為是最佳慣例約定。你可以定義類,如:
public class Email : TagHelper
2.為使 EmailTagHelper
類在我們所有 Razor 視圖中可用,我們將把 addTagHelper
指令添加到 Views/_ViewImports.cshtml 文件:
@using AuthoringTagHelpers
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@addTagHelper "*, AuthoringTagHelpers"
以上代碼我們使用了通配符表明所有的 tag helper 都將在我們的程序集中啟用。 @addTagHelper
之后的第一個字符串指明了要加載的 tag helper(我們使用 “*” 代表所有 tag helper ),第二個字符串 “AuthoringTagHelpers” 指明了此 tag helper 所在的程序集。除此之外要注意的是,使用通配符的第二行,引入了 ASP.NET Core MVC 的 tag helper(這些輔助類在 Tag Helpers 介紹中已經討論過)。是 @addTagHelper
命令使 tag helper 在 Razor 視圖中起作用的。你還可以提供如下所示的 tag helper 的全名(FQN):
@using AuthoringTagHelpers
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@addTagHelper "AuthoringTagHelpers.TagHelpers3.EmailTagHelper, AuthoringTagHelpers"
使用 FQN 給視圖添加 tag helper,首先你要添加 FQN(AuthoringTagHelpers.TagHelpers.EmailTagHelper
),然后是程序集名稱(AuthoringTagHelpers)。多數開發人員喜歡用通配符。Tag Helpers 介紹 詳細了解 tag helper 的添加、刪除、層次結構和通配符。
3.更新 Views/Home/Contact.cshtml 文件中下列變化對應的標簽。
@{
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>
4.運行應用並使用你喜歡的瀏覽器查看 HTML 代碼,你可以校驗 email 標簽都被替換成了鏈接標簽(例如: <a>Support</a>
),Support 和 Marketing 被渲染為鏈接,但是,它們沒有一個 href
屬性能使其正常運行。我們將在下一節修復它。
說明: 比如 HTML 標簽與屬性,Razor 與 C# 中的標簽、類名及屬性是不區分大小寫的。
一個可工作的 email Tag Helper
在這一節中,我們將更新 EmailTagHelper
使其可以為 email 創建一個有效的錨鏈接標簽。我們將修改我們的 tag helper 使其在 Razor 視圖中附加信息(以 mail-to
屬性的形式)並使用它生成鏈接。
參照以下代碼更新 EmailTagHelper
:
public class EmailTagHelper : TagHelper
{
private const string EmailDomain = "contoso.com";
// Can be passed via <email mail-to="..." />.
// Pascal case gets translated into lower-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 形式命名 tag helper 的類名及屬性名會被翻譯成它們的 小寫 kebab 形式。因此,你使用
MailTo
屬性,與使用<email mail-to="value"/>
是等價的。 - 最后一行設置了我們 tag helper 完成的最小化功能的內容。
- 以下代碼展示添加屬性的語法:
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);
}
雖然當前 “href” 在屬性集中不存在,但離實現已經很接近了。你同樣可以使用 output.Attributes.Add
方法在標簽屬性集的最后添加一個 tag helper 屬性。
3.依照以下改動修改 Views/Home/Contact.cshtml 文件標記:
@{
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>
4.運行應用可驗證它生成了正確的鏈接。
說明: 如果你寫的是自閉合的 email 標簽(<email mail-to="Rick" />
),最終的輸出也將是自閉合的。為了啟用寫入僅是一個開始標簽的功能( <email mail-to="Rick">
),你必須如下設置類:
[HtmlTargetElement("email", TagStructure = TagStructure.WithoutEndTag)]
使用自閉合的 email tag helper,輸出將是 <a href="mailto:Rick@contoso.com" />
。自閉合鏈接標簽是無效的 HTML,因此你不應該創建,但你可能想要創建自閉合的 tag helper。Tag helper 是在讀取 tag 后設置 TagMode
屬性的。
異步 email helper
這一節我們將編寫一個異步 email helper。
1.用以下代碼替換 EmailTagHelper
類:
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);
}
}
說明:
- 這個版本使用異步的
ProcessAsync
方法。異步的GetChildContentAsync
返回Task
,其包含了TagHelperContent
。 - 我們使用
output
參數取得 HTML 元素內容。
2.對 Views/Home/Contact.cshtml 文件做以下更改使 tag helper 取得目標 email。
@{
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>
3.運行應用並驗證生成了有效的 email 鏈接。
粗體(Bold) Tag helper
1.添加以下 BoldTagHelper
類到 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>");
}
}
}
/*
* public IActionResult About()
{
ViewData["Message"] = "Your application description page.";
return View("AboutBoldOnly");
// return View();
}
*/
說明:
[HtmlTargetElement]
屬性傳遞一個屬性參數,指定為任何 HTML 元素包含名為 “bold” 的 HTML 屬性,並且類中重寫的Process
方法將被執行。在我們的示例中,Process
方法刪除了 “bold” 屬性且以<strong></strong>
標記包含其中內容。- 因為我們不想替換已有標簽內容,我們必須用
PreContent.SetHtmlContent
方法寫<strong>
開始標簽並用PostContent.SetHtmlContent
方法寫</strong>
閉合標簽。
2.修改 About.cshtml 視圖,添加一個 bold
屬性值。完整代碼如下。
@{
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>
3.運行程序。你可以用你喜歡的瀏覽器審查源代碼,會發現標記已被如願改變。
上面 [HtmlTargetElement]
屬性只指向具有屬性名為 “bold” 的 HTML 標記, <bold>
元素不會被 tag helper 修改。
4.注釋掉 [HtmlTargetElement]
屬性行,其目標將為 <bold>
標簽,也就是 HTML 形式的標記 <bold>
。請記得,默認的名稱轉換將從匹配類名 BoldTagHelper 變為匹配 <bold>
標簽。
5.運行程序可驗證 <bold>
標簽已被 tag helper 處理了。
對一個類配置多個 [HtmlTargetElement]
特性的結果將是對目標作邏輯或判斷。例如,使用下列代碼,bold 標簽或 bold 屬性將被匹配。
[HtmlTargetElement("bold")]
[HtmlTargetElement(Attributes = "bold")]
當在同一個聲明中使用多個屬性時,運行時將視為邏輯與關系。例如,使用如下代碼,HTML 元素必須命名為 “bold” 並具有 “bold” 屬性方能匹配。
[HtmlTargetElement("bold", Attributes = "bold")]
你同樣可以使用 [HtmlTargetElement]
來改變目標元素名稱。例如,如果你想要使 BoldTagHelper
指向目標 <MyBold>
標簽,你應該使用以下屬性:
[HtmlTargetElement("MyBold")]
網站信息 Tag Helper
1.添加一個 Models 文件夾。
2.添加下面的 WebsiteContext
類到 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; }
}
}
3.添加下面的 WebsiteInformationTagHelper
類到 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;
}
}
}
說明:
- 如前文所述,tag helper 將 tag helper 的 C# 類名和屬性 Pascal 形式轉換為 小寫 kebab 形式。盡管如此,在 Razor 中使用
WebsiteInformationTagHelper
你將能輸出<website-information />
。 - 我們並非明確要使用
[HtmlTargetElement]
屬性指定目標元素,因此,website-information
的默認方式將被作為目標。如果你使用下面的屬性(注意它不是 kebab 形式而是匹配類名):
[HtmlTargetElement("WebsiteInformation")]
小寫的 kebab 標簽 <website-information />
不會被匹配。如果你要使用 [HtmlTargetElement]
屬性,你應該使用如下所示的 kebab 形式:
[HtmlTargetElement("Website-Information")]
- 自閉合元素沒有內容。在這個例子,Razor 標記將使用自閉合標簽,但 tag helper 將創建一個section 元素(是指非閉合的並且我們在
section
元素內部輸出內容的元素)。因此,我們需要設置TagMode
為StartTagAndEndTag
來輸出。換言之,你可以注釋掉TagMode
設置行,並用閉合標簽書寫標記。(示例標記在本教程下文中提供) - 下面代碼行中的
$
(美元符號) 使用 interpolated string:
$@"<ul><li><strong>Version:</strong> {Info.Version}</li>
5.在 About.cshtml 視圖添加下列標記。高亮的標記顯示了網站信息。
@using AuthoringTagHelpers.Models
@{
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>
<h3> web site info </h3>
<website-information info="new WebsiteContext {
Version = new Version(1, 3),
CopyrightYear = 1638,
Approved = true,
TagsToShow = 131 }" />
說明: 在 Razor 標記中如下:
<website-information info="new WebsiteContext {
Version = new Version(1, 3),
CopyrightYear = 1638,
Approved = true,
TagsToShow = 131 }" />
Razor 知道 info
屬性是一個類名,不是字符串,你需要寫 C# 代碼。一些非字符 tag helper 屬性不應該寫 @
字符。
6.運行應用,導航到關於視圖查看網站信息。
說明:
- 你可以使用下面的有閉標簽的標記,並移除 tag helper 中有
TagMode.StartTagAndEndTag
的代碼行:
<website-information info="new WebsiteContext {
Version = new Version(1, 3),
CopyrightYear = 1638,
Approved = true,
TagsToShow = 131 }" >
</website-information>
條件 Tag Helper
條件 tag helper 在傳值為真的時候渲染輸出。
1.添加下面的 ConditionTagHelper
類到 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();
}
}
}
}
2.使用下面的標記替換 Views/Home/Index.cshtml 文件中的內容:
@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>
3.用下面的代碼替換 Home
控制器中的 Index
方法:
public IActionResult Index(bool approved = false)
{
return View(new WebsiteContext
{
Approved = approved,
CopyrightYear = 2015,
Version = new Version(1, 3, 3, 7),
TagsToShow = 20
});
}
4.運行應用打開首頁。在有條件的 div
中的標記不會被渲染。在URL請求字符串后添加 ?approved=true
(例如: http://localhost:1235/Home/Index?approved=true)。approved 被設置 true,有條件的標記將被顯示。
說明: 我們使用 nameof 運算符來把屬性識別為目標,而非像我們用 bold tag helper 所做的指定字符串。
[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();
}
}
}
nameof 運算符可以在代碼被重構的時候保護代碼(我們可能想將名稱改為 RedCondition)。
避免 Tag Helper 沖突
在這一節,我們將寫一對自動鏈接的 tag helper。首先將替換包含以 HTTP 為首的鏈接的標記為包含相同 URL(從而產生一個指向 URL 的鏈接)的 HTML 錨標簽。其次將對以 www 為首的 URL 做同樣的操作。
因為這兩個 Helper 密切相關,我們未來將會重構它們,我們將它們放在同一文件。
1.添加下面的 AutoLinker
類到 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}
}
}
說明: AutoLinkerHttpTagHelper
類指向 p
元素且使用 正則 來創建錨。
2.添加下面的標記到 Views/Home/Contact.cshtml 文件末尾:
@{
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>
3.運行程序並驗證 tag helper 正確渲染了錨鏈接。
4.更新 AutoLinker
類,添加 AutoLinkerWwwTagHelper
,它將轉換 www 文字為同樣包含原始 www 文字的鏈接標簽。修改的代碼是下面高亮部分:
[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
}
}
5.運行應用。注意 www 文字被渲染為一條鏈接,但 HTTP 文字卻沒有。如果你在兩個類中打斷點,你可以發現 HTTP tag helper 類先運行。在稍后的教程中我們將看到如何控制其中 tag helper 執行順序。問題在於 tag helper 輸出是被緩存的,而當 WWW tag helper 在運行的時候,它覆蓋了來自 HTTP tag helper 的輸出緩存。我們將使用下面的代碼來修復它:
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
}
}
}
說明: 在第一個 auto-linking tag helper 版本中,我們使用下面的代碼取得目標的內容:
var childContent = await output.GetChildContentAsync();
也就是,我們使用 TagHelperOutput
調用 GetChildContentAsync
傳入了 ProcessAsync
方法。如前面提到的,因為輸出是緩存的,最終運行的 tag helper 成功。我們使用下面的代碼來修復這個問題:
var childContent = output.Content.IsModified ? output.Content.GetContent() :
(await output.GetChildContentAsync()).GetContent();
上面的代碼檢查可見內容是否已被改變,如果已經存在,則從輸出緩沖中獲取內容。
7.運行應用可驗證兩個鏈接如願執行。在表現出我們的自動鏈接 tag helper 是完全正確的同時,它還有個小問題。如果 www tag helper 首先運行,www 鏈接不正常了。添加 Order
重載修改代碼來控制其中 tag 的運行的順序。Order
屬性決定指向同一目標元素的相關 tag helper 的執行順序。順序默認值為 0 ,越小的值被優先執行。
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; }
}
以上代碼將授權 HTTP tag helper 在 WWW tag helper 之前執行。將 Order
改為 最大值
可驗證為 WWW 標簽生成的標記不正確。
審查並檢索子集內容
tag-helper 提供了多種屬性來檢索內容。
GetChildContentAsync
的結果可被附加到output.Content
。- 你可以使用
GetContent
審查GetChildContentAsync
的結果。 - 如果你修改
output.Content
,TagHelper 內容將不被執行或渲染,除非你像在我們的 auto-linker 示例中調用GetChildContentAsync
。
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}
}
}
- 多次調用
GetChildContentAsync
將返回相同的值,而不是重復執行TagHelper
主體,除非你傳入一個 false 參數指示不使用緩存結果。