Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Self-closing TagHelper merges html markup of sibling element

I'm litle confused with behaviour of TagHelper intoduced in ASP.NET Core MVC. Following this tutorial A working email Tag Helper we have opportunity to write self-closing tags. According to the article for this purpose we should use attbute HtmlTargetElement. Class below is demostrated as an example:

 [HtmlTargetElement("email", TagStructure = TagStructure.WithoutEndTag)]
public class EmailTagHelper : TagHelper
{
    private const string EmailDomain = "contoso.com";
    public string MailTo { get; set; }
    public override void Process(TagHelperContext context, TagHelperOutput output)
    {
        output.TagName = "a";
        var address = MailTo + "@" + EmailDomain;
        output.Attributes.SetAttribute("href", "mailto:" + address);
        output.Content.SetContent(address);
    }
}

The markup in razor view like:

<strong>Support:</strong>
    <email mail-to="Support"/><br />
<strong>Marketing:</strong>
    <email mail-to="Marketing"/>

But I have unexpected output:

<strong>Support:</strong>
<a href="mailto:[email protected]">
    <span>Another content</span>
    <strong>Marketing:</strong>
</a>
<a href="mailto:[email protected]"></a>

Why the first anchor tag contains <span> and <strong> tags content?
Without HtmlTargetElement attribute and with closing tags </email> in razor view I have correct behaviour.

like image 968
malonowa Avatar asked Jul 11 '16 10:07

malonowa


1 Answers

I ran this same example and was able to produce this same problem. When debugging, I noticed the TagMode of the output was set to SelfClosing by default. This is not valid for an anchor tag. I then set the tag mode for the anchor to StartTagAndEndTag, and the output was generated as expected.

public override void Process(TagHelperContext context, TagHelperOutput output)
{
    output.TagName = "a";

    // ADD THIS LINE TO YOUR CODE
    output.TagMode = TagMode.StartTagAndEndTag;

    var address = MailTo + "@" + EmailDomain;
    output.Attributes.SetAttribute("href", "mailto:" + address);
    output.Content.SetContent(address);
}

This razor:

<strong>Support:</strong><email mail-to="Support" /><br />
<strong>Marketing:</strong><email mail-to="Marketing" />

Produced this output:

<strong>Support:</strong><a href="mailto:[email protected]">[email protected]</a><br />
<strong>Marketing:</strong><a href="mailto:[email protected]">[email protected]</a>
like image 169
M.Ob Avatar answered Oct 09 '22 07:10

M.Ob