Customizing ASP.NET Core Part 10: TagHelpers – DZone Web Dev | xxxCustomizing ASP.NET Core Part 10: TagHelpers – DZone Web Dev – xxx
菜单

Customizing ASP.NET Core Part 10: TagHelpers – DZone Web Dev

十月 31, 2018 - MorningStar

Over a million developers have joined DZone.
Customizing ASP.NET Core Part 10: TagHelpers - DZone Web Dev

{{announcement.body}}

{{announcement.title}}

Let’s be friends:

Customizing ASP.NET Core Part 10: TagHelpers

DZone’s Guide to

Customizing ASP.NET Core Part 10: TagHelpers

Want to make your life easier? Sure you do! Read on to learn how TagHelpers can assist you in your journey for clean, simple, and nice looking code.

Nov. 19, 18 · Web Dev Zone ·

Free Resource

Join the DZone community and get the full member experience.

Join For Free

Deploying code to production can be filled with uncertainty. Reduce the risks, and deploy earlier and more often. Download this free guide to learn more. Brought to you in partnership with Rollbar.

This was initially planned as the last post of this series because this also was the last part of the talk about customizing ASP.NET Core I did in the past. See the initial post about this series. Now I have three additional customizing topics to talk about. 

In this tenth part of this series, I’m going to write about TagHelpers. The built-in TagHelpers are pretty useful and make pages prettier and more readable. Creating custom TagHelpers will make your life much easier.

About TagHelpers

With TagHelpers, you are able to extend existing HTML tags or to create new tags that get rendered on the server-side. The extensions or the new tags are not visible in the browsers. TagHelpers are only a kind of shortcut to write easier and/or less HTML or Razor code on the server-side. TagHelpers will be interpreted on the server and will produce "real" HTML code for the browsers.

TagHelpers are not a new thing in ASP.NET Core, they’ve been around since the first version. Most existing and built-in TagHelpers are a replacement for the old-fashioned HTML Helpers, which are still around and working in ASP.NET Core to keep the Razor views compatible.

A very basic example of extending HTML tags is the built-in AnchorTagHelper:

<!-- old fashioned HtmlHelper --> <li>@Html.Link("Home", "Index", "Home")</li> <!-- new TagHelper --> <li><a asp-controller="Home" asp-action="Index">Home</a></li>

The HtmlHelper is kinda strange between the HTML tags, for HTML developers. It is hard to read. It is kind of disturbing and interrupts you while reading the code. It is maybe not for ASP.NET Core developers who are used to read that kind of code. But compared to the TagHelpers, it is really ugly. The TagHelpers feel more natural and more like HTML even if they are not and even if they are getting rendered on the server.

Many of the HtmlHelpers can be replaced with a TagHelper.

There are also some new tags built with TagHelpers. Tags that do not exist in HTML, but look like HTML. One example is the EnvironmentTagHelper:

<environment include="Development">     <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />     <link rel="stylesheet" href="~/css/site.css" /> </environment> <environment exclude="Development">     <link rel="stylesheet" href="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.7/css/bootstrap.min.css"             asp-fallback-href="~/lib/bootstrap/dist/css/bootstrap.min.css"             asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute" />     <link rel="stylesheet" href="~/css/site.min.css" asp-append-version="true" /> </environment>

This TagHelper renders or doesn’t render the contents depending on the current runtime environment. In this case, the target environment is the development mode. The first environment tag renders the contents if the current runtime environment is set to Development and the second one renders the contents if it not set to Development. This makes it a useful helper to render debuggable scripts or styles in Development mode and minified and optimized code in any other runtime environment.

Creating Custom TagHelpers

Just as a quick example, let’s assume we need to have any tag configurable as bold and colored in a specific color:

<p strong color="red">Use this area to provide additional information.</p> 

This looks like pretty old fashioned HTML out of the nineties, but this is just to demonstrate a simple TagHelper. But this can be done by a TagHelper that extend any tag that has an attribute called strong

[HtmlTargetElement(Attributes = "strong")] public class StrongTagHelper : TagHelper {     public string Color { get; set; }      public override void Process(TagHelperContext context, TagHelperOutput output)     {         output.Attributes.RemoveAll("strong");          output.Attributes.Add("style", "font-weight:bold;");         if (!String.IsNullOrWhiteSpace(Color))         {             output.Attributes.RemoveAll("style");             output.Attributes.Add("style", $"font-weight:bold;color:{Color};");         }     } }

The first line tells the tag helper to work on tags with a target attribute, strong. This TagHelper doesn’t define its own tag. It provides an additional attribute to specify the color. At least the Process method defined how to render the HTML to the output stream. In this case, it adds some CSS inline styles to the current tag. It also removes the target attribute from the current tag. The color attribute won’t show up.

This will look like this:

<p color="red">Use this area to provide additional information.</p> 

The next sample shows how to define a custom tag using a TagHelper:

public class GreeterTagHelper : TagHelper {     [HtmlAttributeName("name")]     public string Name { get; set; }      public override void Process(TagHelperContext context, TagHelperOutput output)     {         output.TagName = "p";         output.Content.SetContent($"Hello {Name}");     } }

This TagHelper handles a greeter tag that has a property name. In the Process method, the current tag will be changed to a p tag and the new content is set to the current output.

The result looks like this:

<p>Hello Readers</p> 

A More Complex Scenario

The TagHelpers in the last section were pretty basic, just to show how TagHelpers work. The next sample is a little more complex and shows an almost real scenario. This TagHelper renders a table with a list of items. This is a generic TagHelper and shows a real reason to create our own custom TagHelpers. With this, you are able to reuse an isolated piece of view code. You can, for example, wrap Bootstrap components to make them much easier to use, e.g. with just one tag instead of nesting five levels of div tags. Or you can just simplify your Razor views:

public class DataGridTagHelper : TagHelper {     [HtmlAttributeName("Items")]     public IEnumerable<object> Items { get; set; }      public override void Process(TagHelperContext context, TagHelperOutput output)     {         output.TagName = "table";         output.Attributes.Add("class", "table");         var props = GetItemProperties();          TableHeader(output, props);         TableBody(output, props);     }      private void TableHeader(TagHelperOutput output, PropertyInfo[] props)     {         output.Content.AppendHtml("<thead>");         output.Content.AppendHtml("<tr>");         foreach (var prop in props)         {             var name = GetPropertyName(prop);             output.Content.AppendHtml($"<th>{name}</th>");         }         output.Content.AppendHtml("</tr>");         output.Content.AppendHtml("</thead>");     }      private void TableBody(TagHelperOutput output, PropertyInfo[] props)     {         output.Content.AppendHtml("<tbody>");         foreach (var item in Items)         {             output.Content.AppendHtml("<tr>");             foreach (var prop in props)             {                 var value = GetPropertyValue(prop, item);                 output.Content.AppendHtml($"<td>{value}</td>");             }             output.Content.AppendHtml("</tr>");         }         output.Content.AppendHtml("</tbody>");     }      private PropertyInfo[] GetItemProperties()     {         var listType = Items.GetType();         Type itemType;         if (listType.IsGenericType)         {             itemType = listType.GetGenericArguments().First();             return itemType.GetProperties(BindingFlags.Public | BindingFlags.Instance);         }         return new PropertyInfo[] { };     }      private string GetPropertyName(PropertyInfo property)     {         var attribute = property.GetCustomAttribute<DisplayNameAttribute>();         if (attribute != null)         {             return attribute.DisplayName;         }         return property.Name;     }      private object GetPropertyValue(PropertyInfo property, object instance)     {         return property.GetValue(instance);     } }

To use this TagHelper you just need to assign a list of items to this tag:

<data-grid persons="Model.Persons"></data-grid>

In this case, it is a list of people that we get in the Persons property of our current model. The Person class I use here looks like this:

public class Person {     [DisplayName("First name")]     public string FirstName { get; set; }      [DisplayName("Last name")]     public string LastName { get; set; }      public int Age { get; set; }      [DisplayName("Email address")]     public string EmailAddress { get; set; } }

So not all of the properties have a DisplayName attribute, so the fallback in the GetPropertyName method is needed to get the actual property name instead of the DisplayName value.

To use it in production, this TagHelper needs some more checks and validations, but it works:

Customizing ASP.NET Core Part 10: TagHelpers - DZone Web Dev

Now you are able to extend this TagHelper with a lot more features, like sorting, filtering, paging, and so on. 

Conclusion

TagHelpers are pretty useful to reuse parts of the view and to simplify and clean up your views. You can also provide a library with useful view elements. Here are some more examples of already existing TabHelper libraries and samples:

This part was initially planned as the last part of this series, but I found some more interesting topics. If you also have some nice ideas to write about feel free to drop a comment in the introduction post of this series.

In the next post, I’m going to write about how to customize the Hosting of ASP.NET Core Wep Applications: Customizing ASP.NET Core Part 11: Hosting. 

Deploying code to production can be filled with uncertainty. Reduce the risks, and deploy earlier and more often. Download this free guide to learn more. Brought to you in partnership with Rollbar.

Topics:
web dev ,asp.net core

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

Web Dev Partner Resources

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.linkDescription }}

{{ parent.urlSource.name }}

· {{ parent.articleDate | date:’MMM. dd, yyyy’ }} {{ parent.linkDate | date:’MMM. dd, yyyy’ }}


Notice: Undefined variable: canUpdate in /var/www/html/wordpress/wp-content/plugins/wp-autopost-pro/wp-autopost-function.php on line 51