programing

Html에 "활성" 클래스를 추가하는 방법.ASP.NET MVC의 ActionLink

newsource 2023. 5. 25. 22:06

Html에 "활성" 클래스를 추가하는 방법.ASP.NET MVC의 ActionLink

MVC의 부트스트랩 탐색 모음에 "액티브" 클래스를 추가하려고 하는데 다음과 같이 쓰면 활성 클래스가 표시되지 않습니다.

<ul class="nav navbar-nav">
  <li>@Html.ActionLink("Home", "Index", "Home", null, new {@class="active"})</li>
  <li>@Html.ActionLink("About", "About", "Home")</li>
  <li>@Html.ActionLink("Contact", "Contact", "Home")</li>
</ul>

이렇게 하면 올바른 형식의 클래스처럼 보이지만 작동하지 않습니다.

<a class="active" href="/">Home</a>

부트스트랩 설명서에는 'a' 태그를 navbar에서 사용하면 안 된다고 명시되어 있지만, 위의 내용이 HTML에 클래스를 추가하는 올바른 방법이라고 생각합니다.ActionLink.이것을 할 수 있는 다른 방법이 있습니까?

active은 는스에적합야니에 적용되어야 .<li><a>첫 번째 예는 다음과 같습니다. http://getbootstrap.com/components/ #navbar

의 UI와 .ActionLink구축되었는지를 할 수 있는 입니다.이것은 부트스트랩 프레임워크가 어떻게 구축되었는지를 추적할 수 있는 적절한 솔루션입니다.

<ul class="nav navbar-nav">
    <li class="active">@Html.ActionLink("Home", "Index", "Home")</li>
    <li>@Html.ActionLink("About", "About", "Home")</li>
    <li>@Html.ActionLink("Contact", "Contact", "Home")</li>
</ul>

편집:

메뉴를 여러 페이지에서 재사용할 가능성이 높기 때문에 메뉴를 여러 번 복사하여 수동으로 수행하는 것보다 선택한 클래스를 현재 페이지에 따라 자동으로 적용하는 방법이 현명할 것입니다.

은 가장쉬방다포음값함것다사입니을용는하된에에 을 간단하게 입니다.ViewContext.RouteData, 즉, 그Action그리고.Controller다음 하고 있는 할 수 .우리는 다음과 같은 것을 통해 당신이 현재 가지고 있는 것을 기반으로 할 수 있습니다.

<ul class="nav navbar-nav">
    <li class="@(ViewContext.RouteData.Values["Action"].ToString() == "Index" ? "active" : "")">@Html.ActionLink("Home", "Index", "Home")</li>
    <li class="@(ViewContext.RouteData.Values["Action"].ToString() == "About" ? "active" : "")">@Html.ActionLink("About", "About", "Home")</li>
    <li class="@(ViewContext.RouteData.Values["Action"].ToString() == "Contact" ? "active" : "")">@Html.ActionLink("Contact", "Contact", "Home")</li>
</ul>

코드상으로는 예쁘지 않지만, 작업이 완료되고 원하는 경우 메뉴를 부분 보기로 추출할 수 있습니다.훨씬 더 깔끔한 방법이 있습니다만, 이제 막 시작하셨으니 여기서 마치도록 하겠습니다.ASP.NET MVC 학습에 행운을 빕니다!


늦은 편집:

이 좀 것 좀 더 HtmlHelper연장의

편집 03-24-2015: 선택한 동작을 트리거하는 여러 동작과 컨트롤러, 그리고 하위 동작 부분 뷰에서 메서드가 호출될 때의 처리를 허용하기 위해 이 메서드를 다시 작성해야 했습니다. 업데이트를 공유하려고 생각했습니다!

public static string IsSelected(this HtmlHelper html, string controllers = "", string actions = "", string cssClass = "selected")
{
    ViewContext viewContext = html.ViewContext;
    bool isChildAction = viewContext.Controller.ControllerContext.IsChildAction;

    if (isChildAction)
        viewContext = html.ViewContext.ParentActionViewContext;

    RouteValueDictionary routeValues = viewContext.RouteData.Values;
    string currentAction = routeValues["action"].ToString();
    string currentController = routeValues["controller"].ToString();

    if (String.IsNullOrEmpty(actions))
        actions = currentAction;

    if (String.IsNullOrEmpty(controllers))
        controllers = currentController;

    string[] acceptedActions = actions.Trim().Split(',').Distinct().ToArray();
    string[] acceptedControllers = controllers.Trim().Split(',').Distinct().ToArray();

    return acceptedActions.Contains(currentAction) && acceptedControllers.Contains(currentController) ?
        cssClass : String.Empty;
}

.NET Core와 함께 작동:

public static string IsSelected(this IHtmlHelper htmlHelper, string controllers, string actions, string cssClass = "selected")
{
    string currentAction = htmlHelper.ViewContext.RouteData.Values["action"] as string;
    string currentController = htmlHelper.ViewContext.RouteData.Values["controller"] as string;

    IEnumerable<string> acceptedActions = (actions ?? currentAction).Split(',');
    IEnumerable<string> acceptedControllers = (controllers ?? currentController).Split(',');

    return acceptedActions.Contains(currentAction) && acceptedControllers.Contains(currentController) ?
        cssClass : String.Empty;
}

샘플 사용량:

<ul>
    <li class="@Html.IsSelected(actions: "Home", controllers: "Default")">
        <a href="@Url.Action("Home", "Default")">Home</a>
    </li>
    <li class="@Html.IsSelected(actions: "List,Detail", controllers: "Default")">
        <a href="@Url.Action("List", "Default")">List</a>
    </li>
</ul>

확장:

public static MvcHtmlString LiActionLink(this HtmlHelper html, string text, string action, string controller)
{
    var context = html.ViewContext;
    if (context.Controller.ControllerContext.IsChildAction)
        context = html.ViewContext.ParentActionViewContext;
    var routeValues = context.RouteData.Values;
    var currentAction = routeValues["action"].ToString();
    var currentController = routeValues["controller"].ToString();

    var str = String.Format("<li role=\"presentation\"{0}>{1}</li>",
        currentAction.Equals(action, StringComparison.InvariantCulture) &&
        currentController.Equals(controller, StringComparison.InvariantCulture) ?
        " class=\"active\"" :
        String.Empty, html.ActionLink(text, action, controller).ToHtmlString()
    );
    return new MvcHtmlString(str);
}

용도:

<ul class="nav navbar-nav">
    @Html.LiActionLink("About", "About", "Home")
    @Html.LiActionLink("Contact", "Contact", "Home")
</ul>

저는 asp.net mvc에 뷰백 파라미터를 추가하여 이를 수행할 수 있었습니다.여기서 내가 무엇을 했습니까?

된 된가 추가됨ViewBag.Current = "Scheduler"; 페이지의 이 지 동 매 개 변 수 일

레이아웃 페이지에서

<ul class="nav navbar-nav">
     <li class="@(ViewBag.Current == "Scheduler" ? "active" : "") "><a href="@Url.Action("Index","Scheduler")" target="_self">Scheduler</a></li>
 </ul>

이것으로 저의 문제가 해결되었습니다.

조금 늦을 수도 있습니다.하지만 이것이 도움이 되길 바랍니다.

public static class Utilities
{
    public static string IsActive(this HtmlHelper html, 
                                  string control,
                                  string action)
    {
        var routeData = html.ViewContext.RouteData;

        var routeAction = (string)routeData.Values["action"];
        var routeControl = (string)routeData.Values["controller"];

        // both must match
        var returnActive = control == routeControl &&
                           action == routeAction;

        return returnActive ? "active" : "";
    }
}

사용법은 다음과 같습니다.

<div class="navbar-collapse collapse">
    <ul class="nav navbar-nav">
        <li class='@Html.IsActive("Home", "Index")'>
            @Html.ActionLink("Home", "Index", "Home")
        </li>
        <li class='@Html.IsActive("Home", "About")'>
            @Html.ActionLink("About", "About", "Home")
        </li>
        <li class='@Html.IsActive("Home", "Contact")'>
            @Html.ActionLink("Contact", "Contact", "Home")
        </li>
    </ul>
</div>

http://www.codingeverything.com/2014/05/mvcbootstrapactivenavbar.html 에서 참조 자료를 받았습니다.

Easy ASP.NET Core 3.0 및 태그 도우미

[HtmlTargetElement("li", Attributes = "active-when")]
public class LiTagHelper : TagHelper
{
    public string ActiveWhen { get; set; }

    [ViewContext]
    [HtmlAttributeNotBound]
    public ViewContext ViewContextData { get; set; }

    public override void Process(TagHelperContext context, TagHelperOutput output)
    {
        if (ActiveWhen == null)
            return;

        var targetController = ActiveWhen.Split("/")[1];
        var targetAction = ActiveWhen.Split("/")[2];

        var currentController = ViewContextData.RouteData.Values["controller"].ToString();
        var currentAction = ViewContextData.RouteData.Values["action"].ToString();

        if (currentController.Equals(targetController) && currentAction.Equals(targetAction))
        {
            if (output.Attributes.ContainsName("class"))
            {
                output.Attributes.SetAttribute("class", $"{output.Attributes["class"].Value} active");
            }
            else
            {
                output.Attributes.SetAttribute("class", "active");
            }
        }
    }
}

_ViewImports.cs에 포함:

@addTagHelper *, YourAssemblyName

용도:

 <li active-when="/Home/Index">

ASP.NET 코어 & 부트스트랩 4

최신 답변

나는 확장 방법을 기반으로 이 문제를 해결하기 위해 업데이트된 ASP.NET Core 및 Bootstrap 4 호환 방법을 위해 @crush의 깔끔한 솔루션을 재작업했습니다.

public static class LinkExtensions
{
    public static IHtmlContent ActiveActionLink(this IHtmlHelper html, string linkText, string actionName, string controllerName, object routeValues, object htmlAttributes)
    {
        return ActiveActionLink(html, linkText, actionName, controllerName, new RouteValueDictionary(routeValues), HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
    }

    public static IHtmlContent ActiveActionLink(this IHtmlHelper html, string linkText, string actionName, string controllerName, RouteValueDictionary routeValues, IDictionary<string, object> htmlAttributes)
    {
        var routeData = html.ViewContext.RouteData;
        var routeAction = (string)routeData.Values["action"];
        var routeController = (string)routeData.Values["controller"];

        var active = controllerName.Equals(routeController) && actionName.Equals(routeAction);

        using (var writer = new StringWriter())
        {
            writer.WriteLine($"<li class='nav-item {(active ? "active" : "")}'>");
            html.ActionLink(linkText, actionName, controllerName, routeValues, htmlAttributes).WriteTo(writer, HtmlEncoder.Default);
            writer.WriteLine("</li>");
            return new HtmlString(writer.ToString());
        }
    }
}

사용.

<nav class="navbar">
    <div class="collapse navbar-collapse">
        <ul class="navbar-nav">
            @Html.ActiveActionLink("Home", "Index", "Home", null, new { @class = "nav-link" })
            @Html.ActiveActionLink("About", "About", "Home", null, new { @class = "nav-link" })
            @Html.ActiveActionLink("Contact", "Contact", "TimeTracking", null, new { @class = "nav-link" })
        </ul>
    </div>
</nav>

이 질문이 오래된 질문인 것은 알지만, 여기에 제 목소리를 추가하고 싶습니다.링크가 활성화되어 있는지 여부에 대한 지식을 뷰의 컨트롤러에 남겨두는 것이 좋다고 생각합니다.

컨트롤러 작업에서 각 보기에 고유한 값을 설정할 수 있습니다.예를 들어 홈 페이지 링크를 활성화하려면 다음과 같은 작업을 수행합니다.

public ActionResult Index()
{            
    ViewBag.Title = "Home";
    ViewBag.Home = "class = active";
    return View();
}

그러면 제가 보기에, 저는 다음과 같은 것을 쓰겠습니다.

<li @ViewBag.Home>@Html.ActionLink("Home", "Index", "Home", null, new { title = "Go home" })</li>

다른 페이지로 이동할 때 프로그램, 가방 보기라고 합니다.집이 존재하지 않습니다(ViewBag 대신).프로그램이 실행됨). 따라서 class=adm도 렌더링되지 않습니다.저는 이것이 유지보수성과 청결성 모두를 위해 더 깨끗하다고 생각합니다.저는 항상 가능한 한 논리적인 것을 시야에서 제외하고 싶어하는 경향이 있습니다.

데미스가 올린 글을 고려해 볼 때, 저는 당신이 뷰백으로 활동할 자격을 얻을 수 있다고 생각합니다.제목(가장 좋은 방법은 컨텐츠 페이지에 이 내용을 채우는 것입니다._Layout.cshtml링크 막대를 고정할 페이지)를 선택합니다.또한 하위 메뉴 항목을 사용하는 경우에도 잘 작동합니다.

<li class="has-sub @(ViewBag.Title == "Dashboard 1" || ViewBag.Title == "Dashboard 2" ? "active" : "" )">
    <a href="javascript:;">
        <b class="caret"></b>
        <i class="fa fa-th-large"></i>
        <span>Dashboard</span>
    </a>
    <ul class="sub-menu">
        <li class="@(ViewBag.Title == "Dashboard 1" ? "active" : "")"><a href="index.html">Dashboard v1</a></li>
        <li class="@(ViewBag.Title == "Dashboard 2" ? "active" : "")"><a href="index_v2.html">Dashboard v2</a></li>
    </ul>
</li>

이 솔루션은 Asp.net MCV 5에서 간단합니다.

  1. 클래스를 . 를 들어 " " " " (":Utilitarios.cs.

  2. 클래스에서 정적 메서드를 만듭니다.

    public static string IsLinkActive(this UrlHelper url, string action, string controller)
    {
        if (url.RequestContext.RouteData.Values["controller"].ToString() == controller &&
            url.RequestContext.RouteData.Values["action"].ToString() == action)
        {
            return "active";
        }
    
        return "";
    }
    
  3. 이렇게 부르세요.

    <ul class="sidebar-menu" data-widget="tree">
        <li class="header">HEADER</li>
        <li class="@Url.IsLinkActive("Index", "Home")">
            <a href="@Url.Action("Index", "Home")"><i class="fa fa-link"></i> <span>Home</span></a>
        </li>
        <li class="@Url.IsLinkActive("About", "Home")">
            <a href="@Url.Action("About", "Home")"><i class="fa fa-link"></i><span>About</span></a>
        </li>
    </ul>
    

다음을 생성했습니다.HtmlHelper를하는확을 ActiveActionLink에 "입니다.<li>링크를 둘러싸고 있습니다.


public static class LinkExtensions
{
    public static MvcHtmlString ActiveActionLink(this HtmlHelper html, string linkText, string actionName, string controllerName, object routeValues, object htmlAttributes)
    {
        return ActiveActionLink(html, linkText, actionName, controllerName, new RouteValueDictionary(routeValues), HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
    }

    public static MvcHtmlString ActiveActionLink(this HtmlHelper html, string linkText, string actionName, string controllerName, RouteValueDictionary routeValues, IDictionary<string, object> htmlAttributes)
    {
        const string activeClassName = "active";

        var routeData = html.ViewContext.RouteData;

        var routeAction = (string)routeData.Values["action"];
        var routeController = (string)routeData.Values["controller"];

        var active = controllerName.Equals(routeController) && actionName.Equals(routeAction);

        if (active)
        {
            var @class = (string)htmlAttributes["class"];

            htmlAttributes["class"] = string.IsNullOrEmpty(@class)
                ? activeClassName
                : @class + " active";
        }

        var link = html.ActionLink(linkText, actionName, controllerName, routeValues, htmlAttributes);

        return link;
    }
}

사용법은 다음과 같습니다.

@Html.ActiveActionLink("Home", "Index", "Home", new { area = "" }, new { @class = "nav-item nav-link" })

의 해답은 모두 이질에대대솔페를모루사두양용쪽합가다 '페이지.li 그리고a(HtmlHelper를 통해) 태그입니다.@Woles@Crush의 답변 모두 이러한 중복을 제거했는데, 이는 좋은 일이었지만 태그 도우미 대신 HtmlHelper 확장 메서드를 사용하고 있었습니다.태그 도우미를 사용하여 레이저 페이지를 지원하고 싶었습니다.

여기에서 제 전체 게시물을 읽고 소스 코드를 얻을 수 있지만, 요점은 다음과 같습니다.

<bs-menu-link asp-page="/Events/Index" menu-text="Events"></bs-menu-link>

링크가 분명히 활성화된 경우 렌더링:

<li class="active"><a href="/Events">Events</a></li>

는 태그 도우미를 합니다.AnchorTagHelper(asp-page, asp-controller, asp-action 등의지을니다합원속성로으내적)활성화 여부에 대한 '체크'는 이 게시물에 대한 대부분의 답변과 유사합니다.

저는 돔의 "예쁘지 않은" 답변을 수정하여 더 못생겼습니다.두 컨트롤러의 작업 이름(예: 인덱스)이 충돌하는 경우가 있으므로 다음 작업을 수행합니다.

<ul class="nav navbar-nav">
  <li class="@(ViewContext.RouteData.Values["Controller"].ToString() + ViewContext.RouteData.Values["Action"].ToString() == "HomeIndex" ? "active" : "")">@Html.ActionLink("Home", "Index", "Home")</li>
  <li class="@(ViewContext.RouteData.Values["Controller"].ToString() + ViewContext.RouteData.Values["Action"].ToString() == "AboutIndex" ? "active" : "")">@Html.ActionLink("About", "Index", "About")</li>
  <li class="@(ViewContext.RouteData.Values["Controller"].ToString() + ViewContext.RouteData.Values["Action"].ToString() == "ContactHome" ? "active" : "")">@Html.ActionLink("Contact", "Contact", "Home")</li>
</ul>

사용해 볼 수 있습니다.역할 기반 액세스를 기반으로 데이터베이스에서 메뉴를 로드하는 경우, 모든 보기에 사용자가 보기에 따라 활성화할 메뉴의 코드를 작성합니다.

<script type="text/javascript">
        $(document).ready(function () {         
            $('li.active active-menu').removeClass('active active-menu');
            $('a[href="/MgtCustomer/Index"]').closest('li').addClass('active active-menu');
        });
</script>

람다 함수로 가능

@{
string controllerAction = ViewContext.RouteData.Values["Controller"].ToString() + ViewContext.RouteData.Values["Action"].ToString();
    Func<string, string> IsSelected= x => x==controllerAction ? "active" : "";
}

당시의 관습

 @Html.ActionLink("Inicio", "Index", "Home", new { area = "" }, new { @class = IsSelected("HomeIndex")})

ASP.NET MVC에서 비교를 개선하려면 '.ToString'을 추가합니다.

<ul class="nav navbar-nav">
<li class="@(ViewContext.RouteData.Values["Action"].ToString() == "Index" ? "active" : "")">@Html.ActionLink("Home", "Index", "Home")</li>
<li class="@(ViewContext.RouteData.Values["Action"].ToString() == "About" ? "active" : "")">@Html.ActionLink("About", "About", "Home")</li>
<li class="@(ViewContext.RouteData.Values["Action"].ToString() == "Contact" ? "active" : "")">@Html.ActionLink("Contact", "Contact", "Home")</li>

--

우리는 또한 만들 수 있습니다.UrlHelperRequestContext는 MvcHandler입니다.그러므로 저는 이 논리를 레이저 템플릿에 유지하고자 하는 사람이 다음과 같은 방법으로 도움이 될 것이라고 믿습니다.

  1. 프로젝트 루트에서 이름이 지정된 폴더를 만듭니다.AppCode.
  2. 이 " " " 인 .HtmlHelpers.cshtml
  3. 여기에 도우미를 만듭니다.

    @helper MenuItem(string action, string controller)
    {
         var mvcHandler = Context.CurrentHandler as MvcHandler;
         if (mvcHandler != null)
         {
             var url = new UrlHelper(mvcHandler.RequestContext);
             var routeData = mvcHandler.RequestContext.RouteData;
             var currentAction = routeData.Values["action"].ToString();
             var currentController = routeData.Values["controller"].ToString();
             var isCurrent = string.Equals(currentAction, action, StringComparison.InvariantCultureIgnoreCase) &&
                             string.Equals(currentController, controller, StringComparison.InvariantCultureIgnoreCase);
    
            <div class="@(isCurrent ? "active" : "")">
                <div>@url.Action(action, controller)</div>
            </div>
         }   
    }
    
  4. 그런 다음 다음과 같이 사용할 수 있습니다.

    @HtmlHelpers.MenuItem("Default", "Home")
    

누군가에게 도움이 되기를 바랍니다.

저는 돔의 답변의 첫 부분을 기반으로 한 이 해결책을 제안하고 싶습니다.

먼저 "action"과 "controller"라는 두 변수를 정의하고 이를 사용하여 활성 링크를 결정합니다.

{ string controller = ViewContext.RouteData.Values["Controller"].ToString();
string action = ViewContext.RouteData.Values["Action"].ToString();}

그리고 나서:

<ul class="nav navbar-nav">
    <li class="@((controller == "Home" && action == "Index") ? "active" : "")">@Html.ActionLink("Home", "Index", "Home")</li>
    <li class="@((controller == "Home" && action == "About") ? "active" : "")">@Html.ActionLink("About", "About", "Home")</li>
    <li class="@((controller == "Home" && action == "Contact") ? "active" : "")">@Html.ActionLink("Contact", "Contact", "Home")</li>
</ul>

이제는 더 좋아 보이고 더 복잡한 솔루션이 필요하지 않습니다.

@dombenoit의 대답은 효과가 있습니다.유지해야 할 코드가 몇 가지 소개되어 있지만,다음 구문을 확인하십시오.

using (var nav = Html.Bootstrap().Begin(new Nav().Style(NavType.NavBar).SetLinksActiveByControllerAndAction()))
{
    @nav.ActionLink("Link 1", "action1")
    @nav.ActionLink("Link 2", "action2")
    @nav.Link("External Link", "#")
}

의 사용에 주의하십시오..SetLinksActiveByControllerAndAction()방법.

이 구문을 가능하게 하는 이유가 궁금하다면 TwitterBootstrap을 확인하십시오.MVC

저도 해결책을 찾고 있었는데 jQuery가 많은 도움을 주었습니다.먼저, 당은당 'ID'에게 주어야 .<li>요소들.

<li id="listguides"><a href='/Guides/List'>List Guides</a></li>

페이지에서 이한 후 에 어떤 것이 있는지 알려줄 수 .<li>요소는 보기에서 '선택'되어야 합니다.

@section Scripts{
    <script type="text/javascript">
        $('#listguides').addClass('selected');
    </script>
}

고참: 다이필니다합이 합니다.@RenderSection("scripts", required: false)이아웃페서에 앞에 있는 바앞에로이.</body>태그를 클릭하여 해당 섹션을 추가합니다.

저는 이 문제가 우리 중 일부에게 공통적인 문제라는 것을 깨닫고, nuget 패키지를 사용하여 저만의 솔루션을 게시했습니다.아래에서 작동 방식을 확인할 수 있습니다.저는 그것이 유용하기를 바랍니다.

참고: 이 너겟 패키지는 저의 첫 번째 패키지입니다.그러니 틀린 부분이 보이면 피드백 부탁드립니다.감사해요.

  1. 패키지 설치 또는 소스 코드 다운로드 및 프로젝트 추가

    -Install-Package Betalgo.MvcMenuNavigator
    
  2. 열거형에 페이지 추가

    public enum HeaderTop
    {
        Dashboard,
        Product
    }
    public enum HeaderSub
    {
        Index
    }
    
  3. 컨트롤러 또는 작업 맨 위에 필터 추가

    [MenuNavigator(HeaderTop.Product, HeaderSub.Index)]
    public class ProductsController : Controller
    {
        public async Task<ActionResult> Index()
        {
            return View();
        }
    
        [MenuNavigator(HeaderTop.Dashboard, HeaderSub.Index)]
        public async Task<ActionResult> Dashboard()
        {
            return View();
        }
    }
    
  4. 그리고 머리글 레이아웃에 이렇게 사용합니다.

    @{
    var headerTop = (HeaderTop?)MenuNavigatorPageDataNavigatorPageData.HeaderTop;
    var headerSub = (HeaderSub?)MenuNavigatorPageDataNavigatorPageData.HeaderSub;
    }
    <div class="nav-collapse collapse navbar-collapse navbar-responsive-collapse">
    <ul class="nav navbar-nav">
        <li class="@(headerTop==HeaderTop.Dashboard?"active selected open":"")">
            <a href="@Url.Action("Index","Home")">Dashboard</a>
        </li>
        <li class="@(headerTop==HeaderTop.Product?"active selected open":"")">
            <a href="@Url.Action("Index", "Products")">Products</a>
        </li>
    </ul>
    

추가 정보: https://github.com/betalgo/MvcMenuNavigator

선택한 메뉴를 "활성" 상태로 만들기 위한 더 깨끗하고 작은 코드가 있습니다.

 <ul class="navbar-nav mr-auto">
                <li class="nav-item @Html.IfSelected("Index")">
                    <a class="nav-link" href="@Url.Action("Index", "Home")">Home</a>
                </li>
                <li class="nav-item @Html.IfSelected("Controls")">
                    <a class="nav-link" href="@Url.Action("Controls", "Home")">MVC Controls</a>
                </li>
                <li class="nav-item @Html.IfSelected("About")">
                    <a class="nav-link" href="@Url.Action("About", "Home")">About</a>
                </li>
</ul>

 public static string IfSelected(this HtmlHelper html, string action)
        {
            return html
                       .ViewContext
                       .RouteData
                       .Values["action"]
                       .ToString() == action
                            ? " active"
                            : "";
        }

여러 경로에 대한 해결책을 찾았습니다.태그 도우미:

[HtmlTargetElement("li", Attributes = "active-when")]
    public class ActiveTagHelper : TagHelper
    {
        [HtmlAttributeName("active-when")]
        public string ActiveWhen { get; set; }

        [ViewContext]
        [HtmlAttributeNotBound]
        public ViewContext ViewContext { get; set; }

        public override void Process(TagHelperContext context, TagHelperOutput output)
        {
            if (ActiveWhen == null)
                return;

            var hrefs = ActiveWhen.Split(",");

            var currentController = ViewContext.RouteData.Values["controller"].ToString();
            var currentAction = ViewContext.RouteData.Values["action"].ToString();

            foreach (var item in hrefs)
            {
                var targetController = item.Split("/")[1];
                var targetAction = item.Split("/")[2];

                if (currentController.Equals(targetController) && currentAction.Equals(targetAction))
                {
                    if (output.Attributes.ContainsName("class"))
                    {
                        output.Attributes.SetAttribute("class", $"{output.Attributes["class"].Value} active");
                    }
                    else
                    {
                        output.Attributes.SetAttribute("class", "active");
                    }
                }
            }
        }
    }

가져오기:

@addTagHelper *, YourProjectName

용도:

   <li class="nav-item" active-when="/Product/Index,/Product/Add"></li>

레이아웃 페이지의 맨 위에,

@{ var _path = Context.Request.Path.ToString();}

그리고 당신의 나비바에서

<a class="nav-link dropdown-toggle @(_path.Contains("UTBulkFlights") ? "active" : "")">abcLink</a>

전혀 표시되지 않는 경우, 두 개의 @ 기호가 필요하기 때문입니다.

@@class

그러나 부트스트랩 문서(http://getbootstrap.com/components/ #navbar-default)에 따라 "a" 태그가 아닌 "li" 태그의 활성 클래스가 필요할 수 있습니다.

<ul class="nav navbar-nav">
  <li class="active"><a href="#">Home</a></li>
  <li><a href="#">Profile</a></li>
  <li><a href="#">Messages</a></li>
</ul>

따라서 코드는 다음과 같습니다.

<ul class="nav navbar-nav">
  <li class="active">@Html.ActionLink("Home", "Index", "Home", null)</li>
  <li>@Html.ActionLink("About", "About", "Home")</li>
  <li>@Html.ActionLink("Contact", "Contact", "Home")</li>
</ul>

저는 위의 답변을 종합하여 해결책을 만들었습니다.

그래서..

먼저 레이저 블록에서 컨트롤러의 이름 값과 사용자가 호출한 작업을 포함하는 문자열 변수를 만듭니다.

    @{
        string controllerAction =  ViewContext.RouteData.Values["Controller"].ToString() + ViewContext.RouteData.Values["Action"].ToString(); 
    }

그런 다음 HTML과 레이저 코드를 조합하여 사용합니다.

    <ul class="nav navbar-nav">
        <li class="@(controllerAction == "HomeIndex" ? "active" : "" )">@Html.ActionLink("Home", "Index", "Home")</li>
        <li class="@(controllerAction == "AboutIndex" ? "active" : "" )">@Html.ActionLink("About", "Index", "About")</li>
        <li class="@(controllerAction == "HomeContact" ? "active" : "" )">@Html.ActionLink("Contact", "Contact", "Home")</li>
    </ul>

"ViewContext"에 액세스할 필요가 없기 때문에 이것이 좋다고 생각합니다.RouteData.값"은 매번 컨트롤러 이름과 작업 이름을 가져옵니다.

이 문제에 대한 나의 해결책은

<li class="@(Context.Request.Path.Value.ToLower().Contains("about") ? "active " : "" ) nav-item">
                <a class="nav-link" asp-area="" asp-controller="Home" asp-action="About">About</a>
            </li>

링크와 비교할 현재 경로를 반환하는 Html 확장 메서드를 추가하는 것이 더 좋은 방법일 수 있습니다.

제가 한 일은:

메뉴 부분 보기에서 도우미 만들기

 @helper RouterLink(string action, string controller)
{
    var IsActive = ViewContext.RouteData.Values["Controller"].ToString() == controller && ViewContext.RouteData.Values["Action"].ToString() == action;
    <text>href="@Url.Action(action, controller)"</text>if (IsActive){ <text>class="active"</text>}
}

그런 다음 앵커 태그에 다음과 같이 사용합니다.

<li><a @RouterLink("Index","Home")>Home</a></li>

제 앱은 영역이 없었지만 도우미 기능에 다른 변수로 포함될 수도 있습니다.그리고 저는 제가 보기에 활성 수업을 앵커 태그로 전달해야 했습니다.그렇지만li다음과 같이 구성할 수도 있습니다.

ASP.NET Core & Bootstrap 4 & AdminLte

[HtmlTargetElement("a", Attributes = "active-then")]
[HtmlTargetElement("a", Attributes = "asp-action")]
[HtmlTargetElement("a", Attributes = "asp-controller")]
public class AnchorActiveTagHelper : AnchorTagHelper
{
    public AnchorActiveTagHelper(IHtmlGenerator generator) : base(generator)
    {
    }

    [HtmlAttributeName("active-then")]
    public string ActiveWhen { get; set; }

    [ViewContext] [HtmlAttributeNotBound] public ViewContext ViewContextData { get; set; }

    public override void Process(TagHelperContext context, TagHelperOutput output)
    {
        base.Process(context, output);
        
        if (ActiveWhen == null)
            return;

        var currentController = ViewContextData.RouteData.Values["controller"].ToString();
        var currentAction = ViewContextData.RouteData.Values["action"].ToString();

        if (currentController.Equals(Controller) && currentAction.Equals(Action))
        {
            if (output.Attributes.ContainsName("class"))
            {
                output.Attributes.SetAttribute("class", $"{output.Attributes["class"].Value} active");
            }
            else
            {
                output.Attributes.SetAttribute("class", "active");
            }
        }
    }
}    

그리고.

@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@removeTagHelper Microsoft.AspNetCore.Mvc.TagHelpers.AnchorTagHelper, Microsoft.AspNetCore.Mvc.TagHelpers
@addTagHelper *, YourProject.PlatformExtensions

사용.

<li class="nav-item">
    <a asp-controller="Home" asp-action="Index" class="nav-link" active-then="active">
       <i class="nav-icon fas fa-home"></i>
       <p>Home</p>
    </a>
</li>

감사합니다 @WoIIe와 @Shahab

언급URL : https://stackoverflow.com/questions/20410623/how-to-add-active-class-to-html-actionlink-in-asp-net-mvc