加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

asp.net-core-mvc – 确定Tag Helper中的当前路由.这可能吗?

发布时间:2020-12-16 03:59:49 所属栏目:asp.Net 来源:网络整理
导读:在ASP.NET MVC 6项目中,我有以下内容: [Route("help/how-it-works")]public IActionResult HowItWorks() { return View();} 我想创建一个标签助手,如下所示: a class="menu" asp-controller="Help" asp-action="HowItWorks" route-is="help/how-it-works"
在ASP.NET MVC 6项目中,我有以下内容:

[Route("help/how-it-works")]
public IActionResult HowItWorks() {
   return View();
}

我想创建一个标签助手,如下所示:

<a class="menu" asp-controller="Help" asp-action="HowItWorks" route-is="help/how-it-works" css-class="active">How it works</a>

所以route-is标签帮助器将检查当前路由是否为“help / how-it-works”…如果是,则将“active”添加到A标签的css类.

所以我开始创建一个标签助手:

[TargetElement("a",Attributes = "route-is,css-class")]
public class RouteTagHelper : TagHelper
{

public override void Process(TagHelperContext context,TagHelperOutput output)
{

    String routeIs = context.AllAttributes["route-is"].ToString();

    String cssClass = context.AllAttributes["css-class"].ToString();

    if (String.IsNullOrWhiteSpace(cssClass))
        cssClass = "active";

    ViewContext.RouteData.Values.Keys;

}
}// Process

我的问题是如何确定当前路由是否为“help / how-it-works”,以及是否将Css类添加到A标记而不更改其他任何内容.

有没有人知道如何做到这一点?

更新1

使用属性路由时解决了重复值的问题,并添加了Daniel J.G提出的替代方法.

[TargetElement("a",Attributes = RouteIsName)]
[TargetElement("a",Attributes = RouteHasName)]
public class ActiveRouteTagHelper : TagHelper
{
    private const String RouteIsName = "route-is";
    private const String RouteHasName = "route-has";
    private const String RouteCssName = "route-css";

    private IActionContextAccessor _actionContextAccessor;
    private IUrlHelper _urlHelper;

    [HtmlAttributeName(RouteCssName)]
    public String RouteCss { get; set; } = "active";

    [HtmlAttributeName(RouteHasName)]
    public String RouteHas { get; set; }

    [HtmlAttributeName(RouteIsName)]
    public String RouteIs { get; set; }


    public ActiveRouteTagHelper(IActionContextAccessor actionContextAccessor,IUrlHelper urlHelper)
    {

        _actionContextAccessor = actionContextAccessor;
        _urlHelper = urlHelper;

    } // ActiveRouteTagHelper


    public override void Process(TagHelperContext context,TagHelperOutput output)
    {

        IDictionary<String,Object> values = _actionContextAccessor.ActionContext.RouteData.Values;

        String route = _urlHelper.RouteUrl(values.Distinct()).ToLowerInvariant();

        Boolean match = false;

        if (!String.IsNullOrWhiteSpace(RouteIs))
        {

            match = route == RouteIs;

        } else {        

            if (RouteHas != null) {

                String[] keys = RouteHas.Split(',');

            if (keys.Length > 0) 
                match = keys.All(x => route.Contains(x.ToLowerInvariant()));

            }
        }

        if (match)
        {
            TagBuilder link = new TagBuilder("a");
            link.AddCssClass(RouteCss);
            output.MergeAttributes(link);
        }

    } // Process

} // ActiveRouteTagHelper

解决方法

您可以利用您定位相同元素< a>的事实.比默认的MVC AnchorTagHelper.您只需确保在默认的_ViewImports.cshtml中添加助手:

@addTagHelper "*,Microsoft.AspNet.Mvc.TagHelpers"
@addTagHelper "*,WebApplication5"

然后,无论何时执行帮助程序,TagHelperOutput都将包含使用asp-controller和asp-action标记的默认AnchorTagHelper生成的href.

//Get url from href attribute generated by the default AnchorTagHelper
var url = output.Attributes["href"].Value.ToString();

然后,您可以将该URL与将为当前请求生成的URL进行比较:

var currentRoutUrl = this.urlHelper.Action();

Initially I tried the code below,but it does not work when using attribute routing. I can see an entry with key !__route_group in the route values and an exception ArgumentException: An item with the same key has already been added is thrown:

06003

这样做而不是比较当前请求URL是有原因的.这样,无论当前请求url是“/”还是“/ Home / Index”,在这两种情况下,您都会考虑为控制器Home和action Index激活一个链接)

我按照这个想法创建了一个标签助手:

>标签助手将用于< a>已定义属性highlight-active的元素. (这允许css类的属性是可选的,在这种情况下使用默认的活动类):
>标记属性highlight-active从输出html中删除
> class属性与css-active-class属性合并(也从输出html中删除)

代码如下:

[HtmlTargetElement("a",Attributes = "highlight-active")]
public class RouteTagHelper : TagHelper
{
    private IActionContextAccessor actionContextAccessor;
    private IUrlHelper urlHelper;

    public RouteTagHelper(IActionContextAccessor actionContextAccessor,IUrlHelper urlHelper)
    {
        this.actionContextAccessor = actionContextAccessor;
        this.urlHelper = urlHelper;
    }

    //Optional attribute. If not defined,"active" class will be used
    [HtmlAttributeName("css-active-class")]
    public string CssClass { get; set; } = "active";

    public override void Process(TagHelperContext context,TagHelperOutput output)
    {
        //Remove marker attribute
        output.Attributes.Remove(output.Attributes["highlight-active"]);

        //Get the url from href attribute generaed in the default AnchorTagHelper
        var url = output.Attributes["href"].Value.ToString();

        //Add active css class only when current request matches the generated href
        var currentRouteUrl = this.urlHelper.Action();
        if (url == currentRouteUrl)
        {
            var linkTag = new TagBuilder("a");
            linkTag.Attributes.Add("class",this.CssClass);
            output.MergeAttributes(linkTag);
        }
    }
}

因此,您现在可以在主页/索引页面中编写以下内容:

<a class="menu" asp-controller="Home" asp-action="Index" highlight-active>Home</a>
<a class="menu" asp-controller="Home" asp-action="About" highlight-active>About</a>
<a class="menu" asp-controller="Home" asp-action="Index" highlight-active css-active-class="myActiveClass">Home with special class name</a>
<a class="menu" asp-controller="Home" asp-action="Index">Home using default tag helper</a>

其呈现方式如下(无论当前网址是/或/ Home还是/ Home / Index):

<a class="menu active" href="/">Home</a>
<a class="menu" href="/Home/About">About</a>
<a class="menu myActiveClass" href="/">Home with special class</a>
<a class="menu" href="/">Home using default tag helper</a>

PS.当您添加一个直接指定href属性的锚点时,您可能仍需要考虑这些情况(在调用base.Process之前,您可以检测是否已经有一个href).在这种情况下,您可能还希望与当前URL进行比较(通过httpContext.Request).

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读