ASP.NET MVC 5 - 获取当前视图的名称(Razor .cshtml端)

23

我是一名学生,对ASP.NET MVC还比较新,之前主要使用ASP.NET Web Form。(已经习惯了它)

我有一个列表:

<ul class="sidebar bg-grayDark">
    <li class="active">
        <a href="@Url.Action("Index", "Home")">
            <span class="mif-home icon"></span>
            <span class="title">Home</span>
        </a>
    </li>
    <li class="bg-hover-black">
        <a href="@Url.Action("Index", "Product")">
            <span class="mif-shop icon"></span>
            <span class="title">Products</span>
            <span class="counter">14</span>
        </a>
    </li>
    <li class="bg-hover-black">
        <a href="@Url.Action("Index", "Category")">
            <span class="mif-flow-cascade icon"></span>
            <span class="title">Categories</span>
            <span class="counter">9</span>
        </a>
    </li>
    <li class="bg-hover-black">
        <a href="@Url.Action("Index", "User")">
            <span class="mif-users icon"></span>
            <span class="title">Users</span>
            <span class="counter">1</span>
        </a>
    </li>
</ul>
我的目标: 在渲染视图时,我想要将“active”添加到已单击的标记中。 例如:我单击“分类”,然后主页失去其活动类,并向其类添加“active”(以及使用"bg-hover-black"反向操作)。
我以为通过检查实际呈现的视图来完成这个任务,但是我不知道该如何实现。 (我不知道如何检查实际呈现的视图,但可以使用Razor检查条件)
我首先尝试了JavaScript:

    $(function () {
        $('.sidebar').on('click', 'li', function () {
            if (!$(this).hasClass('active')) {
                $('.sidebar li').removeClass('active');
                $(this).addClass('active');
            }
        })
    })
    
但是它不起作用,因为当页面加载时,HTML 会重新呈现带有“Home”部分的“active”。(如果我删除“Home”的“active”,那么除了在点击和页面加载之间什么也没有活动状态)。你有什么解决方案吗?我在网上搜索了很多,但没有找到任何帮助我的东西。对于任何英语错误,我很抱歉,我还在学习中:)。
谢谢, Hellcat8。

大家好,我是一名学生,对ASP.NET MVC还很陌生[...] - Hellcat8
4个回答

30

如果您使用的是将页面命名为控制器的约定,您可以在 Razor 中执行以下操作来获取控制器/页面名称:

@{
 var pageName = ViewContext.RouteData.Values["controller"].ToString();
}

<ul class="sidebar bg-grayDark">
    <li class="@(pageName == "Home" ? "active" : "")">
        <a href="@Url.Action("Index", "Home")">
            <span class="mif-home icon"></span>
            <span class="title">Home</span>
        </a>
    </li>
    <li class="bg-hover-black @(pageName == "Product" ? "active" : "")">
        <a href="@Url.Action("Index", "Product")">
            <span class="mif-shop icon"></span>
            <span class="title">Products</span>
            <span class="counter">14</span>
        </a>
    </li>
    <li class="bg-hover-black @(pageName == "Category" ? "active" : "")">
        <a href="@Url.Action("Index", "Category")">
            <span class="mif-flow-cascade icon"></span>
            <span class="title">Categories</span>
            <span class="counter">9</span>
        </a>
    </li>
    <li class="bg-hover-black @(pageName == "User" ? "active" : "")">
        <a href="@Url.Action("Index", "User")">
            <span class="mif-users icon"></span>
            <span class="title">Users</span>
            <span class="counter">1</span>
        </a>
    </li>
</ul>

这将在页面服务器端设置您的活动类,无需使用JavaScript在客户端执行此操作。


非常感谢!它正在运行! :) 还有一件事:您是否有一些链接,可以让我了解Razor的可能性?在网上,我只能找到像IF和Foreach等基础知识.. :(再次感谢! - Hellcat8
没问题,伙计,很高兴能帮到你 : ) - Anish Patel
1
这是错误的,根据原帖,你得到的是控制器名称,而不是视图名称。 - Matthew Lock
@MatthewLock 因此答案中使用了这样的措辞:“由于您正在使用将页面命名为控制器名称的约定,因此您可以这样做”。 - Anish Patel
1
我认为在顶部的C#代码片段后需要加上一个分号。 - Mark Rogers

8

以下是我为 Razor Pages 项目的 _layout.cshtml 文件所创建的一种层叠样式 Bootstrap 下拉子菜单的方法,其中使用了 active 类来装饰。

主要的解决方案包括:

  • ViewContext.RouteData.Values["page"] 中获取当前页面路由。
  • 使用 Anchor 标签助手而非 @Url.Action()

代码:

<ul class="nav navbar-nav">
    @{
        String pageRoute = ViewContext.RouteData.Values["page"].ToString();
    }
    <li class="dropdown @( pageRoute.Contains("/CustomerModel/") ? "active" : "" )">
        <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Customer-Model <span class="caret"></span></a>
        <ul class="dropdown-menu">
            <li class="@( pageRoute.Contains("/Customers/") ? "active" : "" )"><a asp-page="/CustomerModel/Customers/Index">Customers</a></li>
            <li class="@( pageRoute.Contains("/Partners/")  ? "active" : "" )"><a asp-page="/CustomerModel/CustomerPermissions/Index">CustomerPermissions</a></li>
        </ul>
    </li>
    <li class="dropdown @( pageRoute.Contains("/StaffModel/") ? "active" : "" )">
        <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Staff-Model <span class="caret"></span></a>
        <ul class="dropdown-menu">
            <li class="@( pageRoute.Contains("/Staff/")              ? "active" : "" )"><a asp-page="/StaffModel/Staff/Index">Staff</a></li>
            <li class="@( pageRoute.Contains("/StaffGroups/")        ? "active" : "" )"><a asp-page="/StaffModel/StaffGroups/Index">StaffGroups</a></li>
            <li class="@( pageRoute.Contains("/PermissionsGroups/")  ? "active" : "" )"><a asp-page="/StaffModel/PermissionsGroups/Index">PermissionsGroups</a></li>
            <li class="@( pageRoute.Contains("/AllowedModules/")     ? "active" : "" )"><a asp-page="/StaffModel/AllowedModules/Index">AllowedModules</a></li>
            <li class="@( pageRoute.Contains("/AllowedServices/")    ? "active" : "" )"><a asp-page="/StaffModel/AllowedServices/Index">AllowedServices</a></li>
        </ul>
    </li>
</ul>

5

要获取活动操作或控制器的名称,请使用以下方法

var controllerName = ViewContext.RouteData.Values["controller"].ToString();
var actionName = ViewContext.RouteData.Values["action"].ToString();

接下来,您可以使用以下代码为li元素指定类:

<li class="@(actionName == "HomePage" ? "active":"")"><a href="~/Account/HomePage">Home</a></li>

或者您可以按以下步骤检查两者:
 <li class="@(controllerName =="Account" && actionName == "HomePage" ? "active":"")"><a href="~/Account/HomePage">Home</a></li>

2
确认一下:当用户点击该项目时,您正在更改页面。
因此,您的javascript将运行,但是整个页面将被重新编写,并且您将回到第一个状态(即Home active在标记中)。
要检查当前页面,您可以使用location.href并将其与href url进行比较,类似于以下内容:
$(function() {
    $("ul.sidebar>li").removeClass("active");  // or just not have active in the markup
    $("li>a[href=" + location.href + "]").closest("li").addClass("active");
});

或者,更为稳健的方法是,您可以在视图模型中传递一个令牌(字符串、枚举或常量),然后进行检查,例如:

<ul class='sidebar'>
    <li data-page='home'...
    ...
    <li data-page='categories'...

那么

$(function() { 
    $("li[data-page=@Model.PageName]").addClass("active")

(或者只是在标记中...)
    <li data-page='categories' @(Model.PageName == 'Categories' ? "class=active" : "")>

1
非常感谢您花时间帮助我! :) - Hellcat8

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接