Interpreting ASP. NET 5 & MVC6 series (13): TagHelper, interpreting ASP. NET
In the new version of MVC6, Microsoft provides powerful TagHelper function, so that we can get rid of the following bloated code:
@Html.LabelFor(model => model.FullName)@Html.EditFor(model => model.FullName)@Html.ValidationMessageFor(model => model.FullName)
After the new TagHelper function is introduced, we just need to define it like this. The Code is as follows:
@ AddTagHelper "*, Microsoft. aspNet. mvc. tagHelpers "/* here you need to first reference the namespace where TagHelper is located */<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 discarded, and the custom html attributes are more semantic. The front-end staff are also very comfortable to start, greatly improving the efficiency of front-end developers.
In the default TagHelper implementation, different elements support different custom attributes for different purposes. For example, most elements supportasp-forElement a supportsasp-controllerAndasp-actionAmong others, the input element is the most powerful and supports various types of types and related formats. For detailed implementation, see the table content in the following chapter.
Element
| Attribute |
Description |
| Asp-controller |
Controller name |
| Asp-action |
Action name |
| Asp-host |
Website Host |
| Asp-fragment |
Fragment name of the URL |
| Asp-protocol |
Website protocol (http or https) |
| Asp-route |
Route name |
| Asp-route- |
|
| Href |
Default attribute. If href has a value, no value can be set for other attributes. |
Form Element
| Attribute |
Description |
| Asp-controller |
Controller name |
| Asp-action |
Action name |
| Asp-anti-forgery |
|
| Asp-route- |
|
| Action |
Default attribute. If action has a value, no value can be set for other attributes. |
Input element
| Attribute |
Description |
| Asp- |
Model Field name |
| Asp-format |
Set the Type format as follows: |
| Format |
Standard 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 'mmfile |
File |
The specific time format is as follows:
| Attribute |
Description |
| Date |
{0:yyyy-MM-dd} |
| Datetime |
{0:yyyy-MM-ddTHH:mm:ss.fffK} |
| Datetime-local |
{0:yyyy-MM-ddTHH:mm:ss.fff} |
| Time |
{0:HH:mm:ss.fff} |
Label element
| Attribute |
Description |
| Asp- |
Model Field name |
Textarea Element
| Attribute |
Description |
| Asp- |
Model Field name |
Span Element
| Attribute |
Description |
| Asp-validation- |
Model Field name |
Div Element
| Attribute |
Description |
| Asp-validation-aummary |
ValidationSummary enumerated values: ValidationSummary. All ValidationSummary. ModelOnly ValidationSummary. None. |
Verify the description type. The div element can be rendered only when ValidationSummary. All and ValidationSummary. ModelOnly are selected.
Select Element
| Attribute |
Description |
| Asp- |
Model Field name |
| Asp-items |
Model Field name |
Link Element
| Attribute |
Description |
| Asp-href-include |
|
| Asp-href-exclude |
|
| Asp-fallback-href |
Backup address when href loading fails by default |
| Asp-fallback-href-include |
|
| Asp-fallback-href-exclude |
|
| Asp-fallback-test-class |
Determine the class style used when loading fails |
| Asp-fallback-test-property |
Determines the attributes in the class style used when loading fails. |
| Asp-fallback-test-value |
Determines the value of the attribute in the class style used when the loading fails. |
| Asp-file-version |
|
| Href |
The default css file address. |
The following is an example of link usage. 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" />
The code in this section indicates that by default, the css file on aspnetcdn.com is loaded first. If the loading fails, the css file in the website will be loaded. The judgment condition for loading failure is: detection.carousel-captionStyle is very applied, that is, the elements that apply the styledisplayWhether the property is equal to or notnone. After running the website, the html generated by 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>
We can see that the generated HTML code has two more elements after the link element, oneclass="carousel-caption"The meta element of the attribute.scriptScript tag. The main principle is as follows:
Apply the definedcarousel-captionStyle. Check the meta element'sdisplayWhether the property is equal to or notnone. If not equalnoneTo reload the local backup css file.
Note that the js script here is useddocument.getElementsByTagName("SCRIPT"), Get the lastSCRIPTThe form of the previous sibling element of the tag to obtainmetaElement.
Script Element
| Attribute |
Description |
| Asp-src-include |
|
| Asp-src-exclude |
|
| Asp-fallback-src |
Backup js file address |
| Asp-fallback-src-include |
|
| Asp-fallback-src-exclude |
|
| Asp-fallback-test |
Determine whether the default js file is successfully loaded. |
| Asp-file-version |
|
| Src |
The default js file address. |
scriptThe fallback function of the label element and the link element record the css file type. However, the system checks whether an object exists instead of a class style to determine whether the default js file is successfully loaded, example:
<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. 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>
Generate onescriptTag Element, and then determine whether the jQuery object exists. If it does not exist, it indicates that the loading fails, and then the local backup js file is loaded.
Cache
| Attribute |
Description |
| Vary- |
|
| Vary-by-header |
|
| Vary-by-query |
|
| Vary-by-route |
|
| Vary-by-cookie |
|
| Vary-by-user |
|
| Expires-on |
|
| Expires-after |
|
| Expires-sliding |
|
| Priority |
|
| Enabled |
. |
Use EnvironmentTagHelper to control the output results of different runtime Environments
In many cases, we want to use a set of configuration information in the development environment and another set in the production environment. In this case, we need to use conditional judgment statements, but in the new version of MVC, you can use the Environment element label provided by EnvironmentTagHelper, for example:
<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 are scheduled to use a local js file in the Development environment. Otherwise (the Staging or Production environment), we will first load the cdn file (except for the alternative solution ).
The value in this names is determined based on the searchIHostingEnvironmentOfEnvironmentNameProperties, and compare them, and then perform corresponding processing.
Custom TagHelper
All the TagHelper implementations of MVC inheritMicrosoft.AspNet.Razor.Runtime.TagHelpers.ITagHelperSo we only need to implement this interface to implement custom TagHelper. The interface is defined as follows:
public interface ITagHelper{ int Order { get; } Task ProcessAsync(TagHelperContext context, TagHelperOutput output);}
However, generally, we only need to inherit the default implementation of this interface.TagHelperClass, and reload its virtual MethodProcessThe method is as follows.
1. The controller and action attributes are directly supported on Element.
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 output is automatically generated in the route. attributes. clear (); output. attributes ["href"] = UrlHelper. action (Action, Controller, methodParameters); output. preContent. setContent ("My ");}}}
2. automatically recognize links in 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. Condition judgment
Define a condiction to display this element only when the condition is met. For example, this element is displayed only when Model. Approved is set to true ):
<p condition="Model.Approved" >© @Model.CopyrightYear - My ASP.NET Application</p>
The implementation code is as follows:
[TargetElement ("div")] [TargetElement ("style")] [TargetElement ("p")] public class ConditionTagHelper: TagHelper {public bool? Condition {get; set;} public override void Process (TagHelperContext context, TagHelperOutput output) {// If condition is set and the value is false, if (Condition. hasValue &&! Condition. Value) {output. SuppressOutput ();}}}
4. TagHelper of custom Elements
If we want to define TagHelper for custom elements, we need to comply with the conventions. The sample code is as follows:
public class WebsiteInformationTagHelper : TagHelper{ public WebsiteContext Info { get; set; } public override void Process(TagHelperContext context, TagHelperOutput output) { output.TagName = "section"; output.PostContent.SetContent(string.Format( "<p><strong>Version:</strong> {0}</p>" + Environment.NewLine + "<p><strong>Copyright Year:</strong> {1}</p>" + Environment.NewLine + "<p><strong>Approved:</strong> {2}</p>" + Environment.NewLine + "<p><strong>Number of tags to show:</strong> {3}</p>" + Environment.NewLine, Info.Version.ToString(), Info.CopyrightYear.ToString(), Info.Approved.ToString(), Info.TagsToShow.ToString())); output.SelfClosing = false; }}
Then, we need to usewebsite-informationLabel, andinfoAttribute value is a strongly typed value, for example:
<website-information info="new WebsiteContext { Version = new Version(1, 1), CopyrightYear = 1990, Approved = true, TagsToShow = 30 }"/>
The rendering result is rendered into one containing fourpElementsectionElement.