Anchor Tag Helper,主要是用于构建一个href属性的链接,包含一些对controller、action或者mvc route的处理,它是Mvc6中新增的功能,在NetCore中也是很方便的使用的。
先看看源码定义:
[HtmlTargetElement("a", Attributes = "asp-action")] [HtmlTargetElement("a", Attributes = "asp-controller")] [HtmlTargetElement("a", Attributes = "asp-area")] [HtmlTargetElement("a", Attributes = "asp-fragment")] [HtmlTargetElement("a", Attributes = "asp-host")] [HtmlTargetElement("a", Attributes = "asp-protocol")] [HtmlTargetElement("a", Attributes = "asp-route")] [HtmlTargetElement("a", Attributes = "asp-all-route-data")] [HtmlTargetElement("a", Attributes = "asp-route-*")] public class AnchorTagHelper : TagHelper { /// <summary> /// Creates a new <see cref="T:Microsoft.AspNetCore.Mvc.TagHelpers.AnchorTagHelper" />. /// </summary> /// <param name="generator">The <see cref="T:Microsoft.AspNetCore.Mvc.ViewFeatures.IHtmlGenerator" />.</param> public AnchorTagHelper(IHtmlGenerator generator); /// <inheritdoc /> /// <remarks>Does nothing if user provides an <c>href</c> attribute.</remarks> /// <exception cref="T:System.InvalidOperationException"> /// Thrown if <c>href</c> attribute is provided and <see cref="P:Microsoft.AspNetCore.Mvc.TagHelpers.AnchorTagHelper.Action" />, <see cref="P:Microsoft.AspNetCore.Mvc.TagHelpers.AnchorTagHelper.Controller" />, /// <see cref="P:Microsoft.AspNetCore.Mvc.TagHelpers.AnchorTagHelper.Fragment" />, <see cref="P:Microsoft.AspNetCore.Mvc.TagHelpers.AnchorTagHelper.Host" />, <see cref="P:Microsoft.AspNetCore.Mvc.TagHelpers.AnchorTagHelper.Protocol" />, or <see cref="P:Microsoft.AspNetCore.Mvc.TagHelpers.AnchorTagHelper.Route" /> are /// non-<c>null</c> or if the user provided <c>asp-route-*</c> attributes. Also thrown if <see cref="P:Microsoft.AspNetCore.Mvc.TagHelpers.AnchorTagHelper.Route" /> /// and one or both of <see cref="P:Microsoft.AspNetCore.Mvc.TagHelpers.AnchorTagHelper.Action" /> and <see cref="P:Microsoft.AspNetCore.Mvc.TagHelpers.AnchorTagHelper.Controller" /> are non-<c>null</c>. /// </exception> public override void Process(TagHelperContext context, TagHelperOutput output); /// <inheritdoc /> public override int Order { get; } protected IHtmlGenerator Generator { get; } /// <summary>The name of the action method.</summary> /// <remarks>Must be <c>null</c> if <see cref="P:Microsoft.AspNetCore.Mvc.TagHelpers.AnchorTagHelper.Route" /> is non-<c>null</c>.</remarks> [HtmlAttributeName("asp-action")] public string Action { get; set; } /// <summary>The name of the controller.</summary> /// <remarks>Must be <c>null</c> if <see cref="P:Microsoft.AspNetCore.Mvc.TagHelpers.AnchorTagHelper.Route" /> is non-<c>null</c>.</remarks> [HtmlAttributeName("asp-controller")] public string Controller { get; set; } /// <summary>The name of the area.</summary> /// <remarks>Must be <c>null</c> if <see cref="P:Microsoft.AspNetCore.Mvc.TagHelpers.AnchorTagHelper.Route" /> is non-<c>null</c>.</remarks> [HtmlAttributeName("asp-area")] public string Area { get; set; } /// <summary>The protocol for the URL, such as "http" or "https".</summary> [HtmlAttributeName("asp-protocol")] public string Protocol { get; set; } /// <summary>The host name.</summary> [HtmlAttributeName("asp-host")] public string Host { get; set; } /// <summary>The URL fragment name.</summary> [HtmlAttributeName("asp-fragment")] public string Fragment { get; set; } /// <summary>Name of the route.</summary> /// <remarks> /// Must be <c>null</c> if <see cref="P:Microsoft.AspNetCore.Mvc.TagHelpers.AnchorTagHelper.Action" /> or <see cref="P:Microsoft.AspNetCore.Mvc.TagHelpers.AnchorTagHelper.Controller" /> is non-<c>null</c>. /// </remarks> [HtmlAttributeName("asp-route")] public string Route { get; set; } /// <summary>Additional parameters for the route.</summary> [HtmlAttributeName("asp-all-route-data", DictionaryAttributePrefix = "asp-route-")] public IDictionary<string, string> RouteValues { get; set; } /// <summary> /// Gets or sets the <see cref="T:Microsoft.AspNetCore.Mvc.Rendering.ViewContext" /> for the current request. /// </summary> [HtmlAttributeNotBound] [ViewContext] public ViewContext ViewContext { get; set; } }
其实在早期的mvc中,是有类似的扩展方法的,比如@Html.ActionLink、@Url.Action 等帮助方法。使用也很简单,比如:
@Html.ActionLink("Register", "Register", "Account") <a href="@Url.Action("Register", "Account")">Register</a>
那么,对应的生成的html代码如下:
<a href="/Account/Register">Register</a> <a href="/Account/Register">Register</a>
如果,我们使用anchor tag helper构建同样的一个html的话,就需要用到anchor的扩展属性asp-controller,asp-action,比如:
<a asp-controller="Account" asp-action="Register">Register</a>
Adding Route Parameters
很多时候,比如你想从列表页跳转到详情页去查看或者修改,那么就需要传递一些参数用于区分是哪条数据,这个时候怎么办呢?如果用Anchor Tag Helper处理的话,就需要用到她的另外一个属性asp-route- 前缀开头的。
比如,我想编辑对应记录,我需要传递一个id参数,怎么办呢,那就可以这么用:
<a asp-action="Edit" asp-controller="Todo" asp-route-id="@item.Id">@item.Title</a>
对应的Html代码如下:
<a href="/Todo/Edit/6">Add an appsetting in config and access it in app.</a>
这里,我只是用到了id,所以就构建了一个asp-route-id属性,如果你用到了别的,依然可以自己构建,前提是必须是以“asp-route-” 开头的。
Named Routes
另外一种使用方式,就是利用MapRoute中已经命名好的路由规则处理。比如:
routes.MapRoute( name: "login", template: "login", defaults: new { controller = "Account", action = "Login" });
此时,你可以这么玩:
<a asp-route="login">Login</a>
Protocol, Host and Fragment
anchor tag helper 也可以支持其他一些属性(你可以从源码中定义的属性中可以看到),比如Protocol协议、host、fragment的分片名称。
如果你要用老版本的MVC中的ActionLink方法实现的话,可以这么玩:
@Html.ActionLink("Register", "Register", "Account", "https", "core.todolist.com", "fragment", null, null)
对应的Html代码如下:
<a href="https://core.todolist.com/Account/Register#fragment">Register</a>
如果你要使用anchor tag helper的话,就要用到另外三个属性:asp-protocol、asp-host、asp-fragment。
<a asp-controller="Account" asp-action="Register" asp-protocol="https" asp-host="core.todolist.com" asp-fragment="fragment">Register</a> <!--or with the protocol only --> <a asp-controller="Account" asp-action="Register" asp-protocol="https">Register</a>
很明显,你会觉得这种方式相对可读性更加直观,因为你可以一目了然的看到一些属性的意思和对应的值。另外一个好处就是,可以在只预览html时,不会报错。
that's all~
参考资料:
http://www.davepaquette.com/archive/2015/06/01/mvc-6-anchor-tag-helper.aspx