Guy
Guy

Reputation: 1512

How to Highlight navbar Menu Items in using TagHelpers (Asp.Net.MVC6 6.0.0-rc1.0-final)

I want to generate class="active" in menu links in asp.net 5 1.0.0-rc1-final, to highlight the active menus of the navbar in _Layout.cshtml.
The solution proposed here: Original post by Prashant Adepu works fine in Asp.Net.MVC 6.0.0 beta5. However in 6.0.0 rc1 (asp.net 1.0.0 rc-1 final), it seems impossible to use [ViewContext] decoration since this attribute does not exist.
Is there a way around this?

1) Below is the code with minor adaptation to rc-1.
Everything works except for [ViewContext] which is rejected. Without this attribute, the viewContext will be null in runtime).
2) To run it you should create an asp.net5 WebApplicationX, and add @addTagHelper "WebApplicationX.TagHelpers.MenuLinkTagHelper, WebApplicationX" in _ViewImports.cshtml.
Then just use <menulink controller-name="Home" action-name="About" menu-text="About"></menulink> instead of a regular mvc <a asp-controller="Home" asp-action="Index">Home</a> Anchor.

using Microsoft.AspNet.Mvc;
using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
using Microsoft.AspNet.Razor.TagHelpers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WebApplicationX.TagHelpers
{
    [HtmlTargetElement("menulink", Attributes = "controller-name, action-name, menu-text")]
    public class MenuLinkTagHelper : TagHelper 
    {
        public string ControllerName { get; set; }
        public string ActionName { get; set; }
        public string MenuText { get; set; }
        [ViewContext]                         //*** This is not allowed.***
        public ViewContext ViewContext { get; set; }

        public IUrlHelper _UrlHelper { get; set; }

        public MenuLinkTagHelper(IUrlHelper urlHelper)
        {
            _UrlHelper = urlHelper;
        }

        public override void Process(TagHelperContext context, TagHelperOutput output)
        {
            StringBuilder sb = new StringBuilder();

            string menuUrl = _UrlHelper.Action(ActionName, ControllerName);

            output.TagName = "li";

            var a = new TagBuilder("a");
            a.MergeAttribute("href", $"{menuUrl}");
            a.MergeAttribute("title", MenuText);
            a.InnerHtml.Append(MenuText);

            var routeData = ViewContext.RouteData.Values;
            var currentController = routeData["controller"];
            var currentAction = routeData["action"];

            if (String.Equals(ActionName, currentAction as string, StringComparison.OrdinalIgnoreCase)
                && String.Equals(ControllerName, currentController as string, StringComparison.OrdinalIgnoreCase))
            {
                output.Attributes.Add("class", "active");
            }

            output.Content.SetContent(a.ToString());
        }
    }
}

Upvotes: 0

Views: 1283

Answers (2)

Guy
Guy

Reputation: 1512

Thanks to Danny's help, and after revisiting the original, you can find below the working code for 1.0.0-rc1-final

    using Microsoft.AspNet.Mvc;
    using Microsoft.AspNet.Mvc.Rendering;
    using Microsoft.AspNet.Mvc.ViewFeatures;                    //change for 1.0.0-rc1.0-final
    using Microsoft.AspNet.Razor.TagHelpers;
    using System;
    using System.Text;

namespace WebAppName.TagHelpers
{
    [HtmlTargetElement("menulink", Attributes = "controller-name, action-name, menu-text")]
    public class MenuLinkTagHelper : TagHelper
    {
        public string ControllerName { get; set; }
        public string ActionName { get; set; }
        public string MenuText { get; set; }
        [ViewContext]
        public ViewContext ViewContext { get; set; }

        public IUrlHelper _UrlHelper { get; set; }

        public MenuLinkTagHelper(IUrlHelper urlHelper)
        {
            _UrlHelper = urlHelper;
        }

        public override void Process(TagHelperContext context, TagHelperOutput output)
        {
            StringBuilder sb = new StringBuilder();

            string menuUrl = _UrlHelper.Action(ActionName, ControllerName);

            output.TagName = "li";

            var a = new TagBuilder("a");
            a.MergeAttribute("href", $"{menuUrl}");
            a.MergeAttribute("title", MenuText);
            a.InnerHtml.Append(MenuText);                    //change for 1.0.0-rc1.0-final

            var routeData = ViewContext.RouteData.Values;
            var currentController = routeData["controller"];
            var currentAction = routeData["action"];

            if (String.Equals(ActionName, currentAction as string, StringComparison.OrdinalIgnoreCase)
                && String.Equals(ControllerName, currentController as string, StringComparison.OrdinalIgnoreCase))
            {
                output.Attributes.Add("class", "active");
            }
            output.Content.Append(a);                    //change for 1.0.0-rc1.0-final
        }
    }
}

Upvotes: 0

Danny van der Kraan
Danny van der Kraan

Reputation: 5366

ViewContext attribute is still there. It's in Microsoft.AspNet.Mvc.ViewFeatures, not in Microsoft.AspNet.Mvc.Rendering (where ViewContext class itself is). Make sure to pick the right one. You can check out an example here: https://github.com/DannyvanderKraan/TagHelpers

Upvotes: 2

Related Questions