using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc.Rendering; using Microsoft.AspNetCore.Mvc.ViewFeatures; using Microsoft.AspNetCore.Razor.TagHelpers; using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Teknik.Utilities.TagHelpers { [HtmlTargetElement(Attributes = "is-active-route")] public class ActiveRouteTagHelper : TagHelper { private readonly IHttpContextAccessor _contextAccessor; public ActiveRouteTagHelper(IHttpContextAccessor contextAccessor) { _contextAccessor = contextAccessor; } private IDictionary _routeValues; /// The name of the action method. /// Must be null if is non-null. [HtmlAttributeName("asp-action")] public string Action { get; set; } /// The name of the controller. /// Must be null if is non-null. [HtmlAttributeName("asp-controller")] public string Controller { get; set; } [HtmlAttributeName("asp-page")] public string Page { get; set; } /// Additional parameters for the route. [HtmlAttributeName("asp-all-route-data", DictionaryAttributePrefix = "asp-route-")] public IDictionary RouteValues { get { if (this._routeValues == null) this._routeValues = (IDictionary)new Dictionary((IEqualityComparer)StringComparer.OrdinalIgnoreCase); return this._routeValues; } set { this._routeValues = value; } } /// /// Gets or sets the for the current request. /// [HtmlAttributeNotBound] [ViewContext] public ViewContext ViewContext { get; set; } public override void Process(TagHelperContext context, TagHelperOutput output) { base.Process(context, output); if (ShouldBeActive()) { MakeActive(output); } output.Attributes.RemoveAll("is-active-route"); } private bool ShouldBeActive() { string currentController = string.Empty; string currentAction = string.Empty; if (ViewContext.RouteData.Values["Controller"] != null) { currentController = ViewContext.RouteData.Values["Controller"].ToString(); } if (ViewContext.RouteData.Values["Action"] != null) { currentAction = ViewContext.RouteData.Values["Action"].ToString(); } if (Controller != null) { if (!string.IsNullOrWhiteSpace(Controller) && Controller.ToLower() != currentController.ToLower()) { return false; } if (!string.IsNullOrWhiteSpace(Action) && Action.ToLower() != currentAction.ToLower()) { return false; } } if (Page != null) { if (!string.IsNullOrWhiteSpace(Page) && Page.ToLower() != _contextAccessor.HttpContext.Request.Path.Value.ToLower()) { return false; } } foreach (KeyValuePair routeValue in RouteValues) { if (!ViewContext.RouteData.Values.ContainsKey(routeValue.Key) || ViewContext.RouteData.Values[routeValue.Key].ToString() != routeValue.Value) { return false; } } return true; } private void MakeActive(TagHelperOutput output) { var classAttr = output.Attributes.FirstOrDefault(a => a.Name == "class"); if (classAttr == null) { classAttr = new TagHelperAttribute("class", "active"); output.Attributes.Add(classAttr); } else if (classAttr.Value == null || classAttr.Value.ToString().IndexOf("active") < 0) { output.Attributes.SetAttribute("class", classAttr.Value == null ? "active" : classAttr.Value.ToString() + " active"); } } } }