gpt4 book ai didi

asp.net-core-mvc - 确定标记帮助程序中的当前路线。这可能吗?

转载 作者:行者123 更新时间:2023-12-02 18:47:15 26 4
gpt4 key购买 nike

在 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已经包含默认 AnchorTagHelper 生成的 href使用asp-controllerasp-action标签。

//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:

var currentRouteUrl = this.urlHelper.RouteUrl(
this.actionContextAccessor.ActionContext.RouteData.Values);

这样做而不是比较当前请求 URL 是有原因的。这样,无论当前请求 url 是“/”还是“/Home/Index”,在这两种情况下,您都会考虑激活 Controller Home 和操作 Index 的链接)

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

  • 标签助手将用于 <a>具有属性 highlight-active 的元素定义的。 (这允许 css 类的属性是可选的,在这种情况下使用默认的 active 类):

  • 标记属性 highlight-active从输出 html 中删除

  • 类属性与 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>

呈现如下(无论当前 url 是 //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 的 anchor 时,您可能仍然需要考虑这种情况。属性(您可以在调用 base.Process 之前检查是否已经有 href )。在这种情况下,您可能还想与当前 url 进行比较(通过 httpContext.Request)。

关于asp.net-core-mvc - 确定标记帮助程序中的当前路线。这可能吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32912551/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com