[译]【NetCore学习笔记之Anchor TagHelper】ASP.NET Core MVC Anchor Tag Helper

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

 

posted @ 2016-09-02 10:25  iMhager  阅读(730)  评论(0编辑  收藏  举报