扩展为标签助手的方法
Method that expands into tag-helper
我在 cshtml
文件中有以下方法。它只是扩展为两个 label
元素。第一个是普通的 label
元素。然而,第二个使用标签助手:
async Task field(string str)
{
<label for="@str">@str</label>
<label asp-for="@str">@str</label>
}
下面是我在 cshtml
文件中定义它并调用它一次的方法:
@{
{
async Task field(string str)
{
<label for="@str">@str</label>
<label asp-for="@str">@str</label>
}
await field("abc");
}
}
如果我 'view source' 结果,我会看到以下内容:
<label for="abc">abc</label>
<label for="str">abc</label>
请注意,@str
参数在第一种情况下已正确传递和使用,但在第二种情况下却没有。因此,将参数传递给此处的标签助手变体似乎存在问题。
关于如何解决这个问题有什么建议吗?
在我看来,参数已成功传递给标签助手变体。但是标签 asp-for 属性将呈现为带有 asp-for ModelExpression 的名称值(str
)而不是 ModelExpression 的模型值(abc
)的 for 属性。
根据label taghelper source codes,可以发现tag helper会调用Generator.GenerateLabel方法生成label标签html内容。
Generator.GenerateLabel有五个参数,第三个参数表达式用于生成标签的for属性。
var tagBuilder = Generator.GenerateLabel(
ViewContext,
For.ModelExplorer,
For.Name,
labelText: null,
htmlAttributes: null);
如果您想显示 for 属性的 str 值,您应该创建一个自定义标签 labeltaghelper。
更多详情,您可以参考以下代码:
[HtmlTargetElement("label", Attributes = "asp-for")]
public class ExtendedAspForTagHelper:LabelTagHelper
{
public ExtendedAspForTagHelper(IHtmlGenerator generator)
: base(generator)
{
}
public override int Order => -10000;
//public override void Process(TagHelperContext context, TagHelperOutput output)
//{
// base.Process(context, output);
// if (!output.Attributes.TryGetAttribute("maxlength", out TagHelperAttribute maxLengthAttribute))
// {
// return;
// }
// var description = $"Only <b>{maxLengthAttribute.Value}</b> characters allowed!";
// output.PostElement.AppendHtml(description);
//}
public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
if (output == null)
{
throw new ArgumentNullException(nameof(output));
}
var tagBuilder = Generator.GenerateLabel(
ViewContext,
For.ModelExplorer,
For.Model.ToString(),
labelText: null,
htmlAttributes: null);
if (tagBuilder != null)
{
output.MergeAttributes(tagBuilder);
// Do not update the content if another tag helper targeting this element has already done so.
if (!output.IsContentModified)
{
// We check for whitespace to detect scenarios such as:
// <label for="Name">
// </label>
var childContent = await output.GetChildContentAsync();
if (childContent.IsEmptyOrWhiteSpace)
{
// Provide default label text (if any) since there was nothing useful in the Razor source.
if (tagBuilder.HasInnerHtml)
{
output.Content.SetHtmlContent(tagBuilder.InnerHtml);
}
}
else
{
output.Content.SetHtmlContent(childContent);
}
}
}
}
}
在 _ViewImports.cshtml
中改进这个标签助手
@addTagHelper *,[yournamespace]
结果:
我在 cshtml
文件中有以下方法。它只是扩展为两个 label
元素。第一个是普通的 label
元素。然而,第二个使用标签助手:
async Task field(string str)
{
<label for="@str">@str</label>
<label asp-for="@str">@str</label>
}
下面是我在 cshtml
文件中定义它并调用它一次的方法:
@{
{
async Task field(string str)
{
<label for="@str">@str</label>
<label asp-for="@str">@str</label>
}
await field("abc");
}
}
如果我 'view source' 结果,我会看到以下内容:
<label for="abc">abc</label>
<label for="str">abc</label>
请注意,@str
参数在第一种情况下已正确传递和使用,但在第二种情况下却没有。因此,将参数传递给此处的标签助手变体似乎存在问题。
关于如何解决这个问题有什么建议吗?
在我看来,参数已成功传递给标签助手变体。但是标签 asp-for 属性将呈现为带有 asp-for ModelExpression 的名称值(str
)而不是 ModelExpression 的模型值(abc
)的 for 属性。
根据label taghelper source codes,可以发现tag helper会调用Generator.GenerateLabel方法生成label标签html内容。
Generator.GenerateLabel有五个参数,第三个参数表达式用于生成标签的for属性。
var tagBuilder = Generator.GenerateLabel(
ViewContext,
For.ModelExplorer,
For.Name,
labelText: null,
htmlAttributes: null);
如果您想显示 for 属性的 str 值,您应该创建一个自定义标签 labeltaghelper。
更多详情,您可以参考以下代码:
[HtmlTargetElement("label", Attributes = "asp-for")]
public class ExtendedAspForTagHelper:LabelTagHelper
{
public ExtendedAspForTagHelper(IHtmlGenerator generator)
: base(generator)
{
}
public override int Order => -10000;
//public override void Process(TagHelperContext context, TagHelperOutput output)
//{
// base.Process(context, output);
// if (!output.Attributes.TryGetAttribute("maxlength", out TagHelperAttribute maxLengthAttribute))
// {
// return;
// }
// var description = $"Only <b>{maxLengthAttribute.Value}</b> characters allowed!";
// output.PostElement.AppendHtml(description);
//}
public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
if (output == null)
{
throw new ArgumentNullException(nameof(output));
}
var tagBuilder = Generator.GenerateLabel(
ViewContext,
For.ModelExplorer,
For.Model.ToString(),
labelText: null,
htmlAttributes: null);
if (tagBuilder != null)
{
output.MergeAttributes(tagBuilder);
// Do not update the content if another tag helper targeting this element has already done so.
if (!output.IsContentModified)
{
// We check for whitespace to detect scenarios such as:
// <label for="Name">
// </label>
var childContent = await output.GetChildContentAsync();
if (childContent.IsEmptyOrWhiteSpace)
{
// Provide default label text (if any) since there was nothing useful in the Razor source.
if (tagBuilder.HasInnerHtml)
{
output.Content.SetHtmlContent(tagBuilder.InnerHtml);
}
}
else
{
output.Content.SetHtmlContent(childContent);
}
}
}
}
}
在 _ViewImports.cshtml
@addTagHelper *,[yournamespace]
结果: