Как выделить элементы меню панели навигации с помощью TagHelpers (Asp.Net.MVC6 6.0.0-rc1.0-final)

Я хочу сгенерировать class="active" в ссылках меню в asp.net 5 1.0.0-rc1-final, чтобы выделить активные меню панели навигации в _Layout.cshtml.
Предлагаемое здесь решение: Исходное сообщение от Прашанта Adepu отлично работает в Asp.Net.MVC 6.0.0 beta5. Однако в 6.0.0 rc1 (asp.net 1.0.0 rc-1 final) кажется невозможным использовать оформление [ViewContext], поскольку этот атрибут не существует.< br> Есть ли способ обойти это?

1) Ниже приведен код с небольшой адаптацией к rc-1.
Все работает, кроме [ViewContext], который отклонен. Без этого атрибута viewContext будет нулевым во время выполнения).
2) Чтобы запустить его, вы должны создать asp.net5 WebApplicationX и добавить @addTagHelper "WebApplicationX.TagHelpers.MenuLinkTagHelper, WebApplicationX" в _ViewImports.cshtml.
Тогда просто используйте <menulink controller-name="Home" action-name="About" menu-text="About"></menulink> вместо обычного 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());
        }
    }
}

person Guy    schedule 10.03.2016    source источник


Ответы (2)


Атрибут ViewContext все еще существует. Он находится в Microsoft.AspNet.Mvc.ViewFeatures, а не в Microsoft.AspNet.Mvc.Rendering (где находится сам класс ViewContext). Убедитесь, что выбрали правильный. Вы можете посмотреть пример здесь: https://github.com/DannyvanderKraan/TagHelpers

person Danny van der Kraan    schedule 10.03.2016
comment
Спасибо, действительно помогает. однако по какой-то причине я получаю в выводе от a.ToString() Microsoft.AspNet.Mvc.Rendering.TagBuilder вместо фактического Anchor. Мне нужно будет сравнить дальше с оригиналом и понять, почему это так. Я обновлю, как только решу это. - person Guy; 10.03.2016

Благодаря помощи Дэнни и повторному просмотру оригинала вы можете найти ниже рабочий код для 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
        }
    }
}
person Guy    schedule 10.03.2016