Interpretation of ASP. NET 5 MVC6 Series Tutorials (13): TagHelper

  • 2021-07-26 07:28:26
  • OfStack

In the new version of MVC6, Microsoft provides powerful TagHelper functionality to get rid of the following bloated code:


@Html.LabelFor(model => model.FullName)
@Html.EditFor(model => model.FullName)
@Html.ValidationMessageFor(model => model.FullName)

After the introduction of the new function TagHelper, we only need to define it like this, and the code is as follows:


@addTagHelper "*, Microsoft.AspNet.Mvc.TagHelpers" /*  Here you need to first reference TagHelper Namespace in which  */

<label asp-for="FullName" class="control-label col-md-2"></label>
<div class="col-md-10">
 <input asp-for="FullName" class="form-control" />
 <span asp-validation-for="FullName"></span>
</div>

In this way, the server-side code is thrown away, and it is more semantic to use the custom html attribute, which makes the front-end personnel comfortable to drive, and greatly improves the efficiency of the front-end developers.

In the default TagHelper implementation, different elements support different custom attributes for different purposes, for example, most elements support asp-for And the a element supports asp-controller And asp-action The input element is the most powerful and supports various types of type and related formats. For detailed implementation, please refer to the table contents in the following sections.

A element

属性 描述
asp-controller Controller的名称
asp-action Action的名称
asp-host 网站的Host
asp-fragment URL的fragment名称
asp-protocol 网站协议(http或https)
asp-route Route名称
asp-route-
href 默认属性,如果href有值,则其它属性都不能设置任何值。

Form element

属性 描述
asp-controller Controller的名称
asp-action Action的名称
asp-anti-forgery
asp-route-
action 默认属性,如果action有值,则其它属性都不能设置任何值。

Input element

属性 描述
asp-for 模型字段的名称
asp-format 设置Type格式,具体如下:
格式 标准类型
HiddenInput hidden
Password password
Text text
PhoneNumber tel
Url url
EmailAddress email
Date date
DateTime datetime
DateTime-local datetime-local
Time time
Byte/SByte/Int16/UInt16/Int32/UInt32/Int64/UInt64/Single/Double number
Boolean checkbox
Decimal text
String text
IFormFile file
IEnumerable`IFormFile file

The specific format of time is as follows:

属性 描述
date CODE_TAG_REPLACE_MARK_3
datetime CODE_TAG_REPLACE_MARK_4
datetime-local CODE_TAG_REPLACE_MARK_5
time CODE_TAG_REPLACE_MARK_6

Label element

属性 描述
asp-for 模型字段的名称

textarea element

属性 描述
asp-for 模型字段的名称

span element

属性 描述
asp-validation-for 模型字段的名称

div element

属性 描述
asp-validation-aummary ValidationSummary枚举值:
ValidationSummary.All
ValidationSummary.ModelOnly
ValidationSummary.None。

Verify the description type and render the div element only if ValidationSummary. All and ValidationSummary. ModelOnly are selected.

select element

属性 描述
asp-for 模型字段名称
asp-items 模型字段名称

link element

属性 描述
asp-controller Controller的名称
asp-action Action的名称
asp-anti-forgery
asp-route-
action 默认属性,如果action有值,则其它属性都不能设置任何值。
0

Examples of using link are as follows, for example, we define the following code:


<link rel="stylesheet" 
href="//ajax.aspnetcdn.com/ajax/bootstrap-touch-carousel/0.8.0/css/bootstrap-touch-carousel.css"
asp-fallback-href="~/lib/bootstrap-touch-carousel/css/bootstrap-touch-carousel.css"
asp-fallback-test-class="carousel-caption" 
asp-fallback-test-property="display" 
asp-fallback-test-value="none" />

Then this section of code indicates that the default first load css file on aspnetcdn. com, if the loading fails, then load the css file in the local website. The judgment condition of loading failure is: detection carousel-caption Style 10 is applied, that is, the element to which the style is applied display Property is equal to none . After running the website, the generated html of this code is as follows:


<link rel="stylesheet" href="//ajax.aspnetcdn.com/ajax/bootstrap-touch-carousel/0.8.0/css/bootstrap-touch-carousel.css" />
<meta name="x-stylesheet-fallback-test" class="carousel-caption" />
<script>
 !function (a, b, c) {
  var d, e = document,
   f = e.getElementsByTagName("SCRIPT"),
   g = f[f.length - 1].previousElementSibling,
   h = e.defaultView && e.defaultView.getComputedStyle ? e.defaultView.getComputedStyle(g) : g.currentStyle;

  if (h && h[a] !== b) {
   for (d = 0; d < c.length; d++) {
    e.write('<link rel="stylesheet" href="' + c[d] + '"/>')
   }
  }
 }("display", "none", ["\/lib\/bootstrap-touch-carousel\/css\/bootstrap-touch-carousel.css"]);
</script>

From this, we can see that the generated HTML code has two more elements after the link element, and one is with asp-controller0 meta element of attribute, 1 is script Script label. Its main principles are as follows:

Applies the defined on an meta element carousel-caption Style. The of the meta element is detected by the JS code display Property is equal to none . If it is not equal to none To reload the local alternate css file.

Note that the js script here uses the document.getElementsByTagName("SCRIPT") Gets the last 1 SCRIPT Label to get the form of the last sibling element of the meta Element.

script Element

属性 描述
asp-controller Controller的名称
asp-action Action的名称
asp-anti-forgery
asp-route-
action 默认属性,如果action有值,则其它属性都不能设置任何值。
1

script The fallback function of the tag element and the link element record the css file type, but what is judged here is not the class style, but whether an object exists is detected to judge whether the default js file is loaded successfully. Examples are as follows:


<script src="//ajax.aspnetcdn.com/ajax/jquery/jquery-1.10.2.min.js"
 asp-fallback-src="~/lib/jquery/jquery.min.js"
 asp-fallback-test="window.jQuery">
</script>

The generated HTML code is relatively simple, and the example is as follows:


<script src="//ajax.aspnetcdn.com/ajax/jquery/jquery-1.10.2.min.js">
</script>
<script>(window.jQuery||document.write("<script src=\"\/lib\/jquery\/jquery.min.js\"><\/script>"));</script>

One more was generated script Tag element, and then determine whether the jQuery object exists. If it does not exist, it means that the load failed, and then load the local standby js file.

Cache

属性 描述
asp-controller Controller的名称
asp-action Action的名称
asp-anti-forgery
asp-route-
action 默认属性,如果action有值,则其它属性都不能设置任何值。
2

Using EnvironmentTagHelper to control the output results of different running environments

In many cases, we want to use one set of configuration information in the development environment and another set in the production environment. At this time, we need to use conditional judgment statements. However, in the new version of MVC, it is enough to use the Environment element tag provided by EnvironmentTagHelper. The example is as follows:


<environment names="Development">
 <script src="~/lib/jquery/jquery.js"></script>
 <script src="~/lib/bootstrap/js/bootstrap.js"></script>
 <script src="~/lib/hammer.js/hammer.js"></script>
 <script src="~/lib/bootstrap-touch-carousel/js/bootstrap-touch-carousel.js"></script>
</environment>
<environment names="Staging,Production">
 <script src="//ajax.aspnetcdn.com/ajax/jquery/jquery-1.10.2.min.js"
   asp-fallback-src="~/lib/jquery/jquery.min.js"
   asp-fallback-test="window.jQuery">
 </script>
 <script src="//ajax.aspnetcdn.com/ajax/bootstrap/3.0.0/bootstrap.min.js"
   asp-fallback-src="~/lib/bootstrap/js/bootstrap.min.js"
   asp-fallback-test="window.jQuery">
 </script>
 <script src="//ajax.aspnetcdn.com/ajax/hammer.js/2.0.4/hammer.min.js"
   asp-fallback-src="~/lib/hammer.js/hammer.js"
   asp-fallback-test="window.Hammer">
 </script>
 <script src="//ajax.aspnetcdn.com/ajax/bootstrap-touch-carousel/0.8.0/js/bootstrap-touch-carousel.js"
   asp-fallback-src="~/lib/bootstrap-touch-carousel/js/bootstrap-touch-carousel.js"
   asp-fallback-test="window.Zepto">
 </script>
</environment>

In the above code, we decided to use the local js file if it is an Development environment, or load the cdn file first (except for the alternate scheme) if it is an Staging or Production environment.

The value judgment in names is based on finding IHostingEnvironment Adj. EnvironmentName Property and compare it with it, and then process it accordingly.

Custom TagHelper

MVC All implementations of TagHelper inherit Microsoft.AspNet.Razor.Runtime.TagHelpers.ITagHelper Interface, so we can implement a custom TagHelper only by implementing this interface, which is defined as follows:


public interface ITagHelper
{
 int Order { get; }
 Task ProcessAsync(TagHelperContext context, TagHelperOutput output);
}

However, when we customize, we only need to inherit the default implementation of the interface TagHelper Class and overloads its virtual methods Process Method is enough. Here are a few examples. Let's study 1 in detail.

1. Support controller and action attributes directly on a elements


public class ATagHelper : TagHelper
{
 [Activate]
 public IUrlHelper UrlHelper { get; set; }

 public string Controller { get; set; }

 public string Action { get; set; }

 public override void Process(TagHelperContext context, TagHelperOutput output)
 {
  if (Controller != null && Action != null)
  {
   var methodParameters = output.Attributes.ToDictionary(attribute => attribute.Key,
                 attribute => (object)attribute.Value);

   //  Delete all attributes Because the route can already be automatically generated 
   output.Attributes.Clear();

   output.Attributes["href"] = UrlHelper.Action(Action, Controller, methodParameters);

   output.PreContent.SetContent("My ");
  }
 }
}

2. Automatically identify links in Text text and extract them


[TargetElement("p")]
public class AutoLinkerTagHelper : TagHelper
{
 public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
 {
  var childContent = await context.GetChildContentAsync();

  // Find Urls in the content and replace them with their anchor tag equivalent.
  output.Content.SetContent(Regex.Replace(
   childContent.GetContent(),
   @"\b(?:https?://|www\.)(\S+)\b",
   "<strong><a target=\"_blank\" href=\"http://$0\">$0</a></strong>"));
 }
}

3. Conditional judgment

Define an condiction that is displayed only if it meets the criteria, as shown below (this element is displayed only if Model. Approved is true):


@addTagHelper "*, Microsoft.AspNet.Mvc.TagHelpers" /*  Here you need to first reference TagHelper Namespace in which  */

<label asp-for="FullName" class="control-label col-md-2"></label>
<div class="col-md-10">
 <input asp-for="FullName" class="form-control" />
 <span asp-validation-for="FullName"></span>
</div>
0

The implementation code is as follows:


@addTagHelper "*, Microsoft.AspNet.Mvc.TagHelpers" /*  Here you need to first reference TagHelper Namespace in which  */

<label asp-for="FullName" class="control-label col-md-2"></label>
<div class="col-md-10">
 <input asp-for="FullName" class="form-control" />
 <span asp-validation-for="FullName"></span>
</div>
1

4. TagHelper for custom elements

If we were to define TagHelper for a custom element, we would conform to the convention specification, and the sample code is as follows:


@addTagHelper "*, Microsoft.AspNet.Mvc.TagHelpers" /*  Here you need to first reference TagHelper Namespace in which  */

<label asp-for="FullName" class="control-label col-md-2"></label>
<div class="col-md-10">
 <input asp-for="FullName" class="form-control" />
 <span asp-validation-for="FullName"></span>
</div>
2

We need to use the website-information Label and set the info Property to assign a strongly typed value, as shown in the following example:


<website-information info="new WebsiteContext {
        Version = new Version(1, 1),
        CopyrightYear = 1990,
        Approved = true,
        TagsToShow = 30 }"/>

The rendering result is rendered to 1 containing 4 p Element's section Element.


Related articles: