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>