As well as using the out the box tag helpers provided in MVC 6 it is possible to create custom tag helpers to output your own Html.

Say we want to display a person’s contact details we can create a tag helper that turns simple markup into more verbose markup including an individual’s contact information.

Tag helpers inherit from the abstract TagHelper class that defines a virtual method Process (and also ProcessAsync), this is there main code to generate the output is based. The Process method takes two parameters a TagHelperContext object, containing information about the current tag, and a TagHelperOutput object that represents the output generated by the tag helper.

The TagHelperOutput object has properties for TagName, PreContent, Content and PostContent. The content properties have a SetContent method enabling content to be set and allows you to build up content in the structure defined below.

<TagName>
{{PreContent}}
{{Content}}
{{PostContent}}
</TagName>

Below is an example of the ContactTagHelper that takes one simple property to define the style of the output and a complex property to accept the contact model.

using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.AspNet.Razor.Runtime.TagHelpers;

namespace MyProject.TagHelpers
{
    public enum ContactDetailStyle { FullName, FirstNameOnly } 

    [TargetElement("div", Attributes = ContactAttributeName + "," + ContactStyleName)]
    public class ContactTagHelper : TagHelper
    {
        private const string ContactAttributeName = "contact-details";
        private const string ContactStyleName = "contact-style";

        [HtmlAttributeName(ContactStyleName)]
        public ContactDetailStyle Style { get; set; }

        [HtmlAttributeName(ContactAttributeName)]
        public ContactDetails Contact { get; set; } // class with three properties (name, email tel

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

            string name = Style == ContactDetailStyle.FullName ? $"{Contact.FirstName} {Contact.LastName}" : Contact.FirstName;

            var nameEl = new TagBuilder("h2");
            nameEl.SetInnerText(name);

            var email = new TagBuilder("a");
            email.MergeAttribute("href", "mailto:" + Contact.Email);
            email.SetInnerText(Contact.Email);

            var contactDetails = new TagBuilder("p");
            contactDetails.InnerHtml = $"{email}<br />{Contact.Tel}";

            output.Content.SetContent($"{nameEl}{contactDetails}");
        }
    }
}

We can then use the tag helper by adding @addTagHelper "*, {{my assembly name here}}" to the top of our view (or including it in our _ViewImports.cshtml file). Then by simply adding an attribute to a div the tag helper will replace the outputted html with our more verbose markup including the contact’s information.

@addTagHelper "*, MyProject"
@model ContactDetails

<div contact-details="Model" contact-style="FirstNameOnly"></div>