在MVC 3 Razor中获得活动页面链接的更好方法

Jen*_*ens 54 c# razor asp.net-mvc-3

当我希望特定菜单链接在给定页面上处于活动状态时,我在Razor中使用这种方法:

在主布局上,我有这些检查:

var active = ViewBag.Active;
const string ACTIVE_CLASS = "current";

if (active == "home")
{
    ViewBag.ActiveHome = ACTIVE_CLASS;
}
if (active == "products")
{
    ViewBag.ActiveProducts = ACTIVE_CLASS;
}
Run Code Online (Sandbox Code Playgroud)

等等

主布局上的html菜单:

<ul>
<li class="@ViewBag.ActiveHome"><a href="/">Home</a></li>
<li class="@ViewBag.ActiveProducts"><a href="@Url.Action("index", "products")">Products</a></li>
</ul>
Run Code Online (Sandbox Code Playgroud)

指定在不同视图上使用的布局页面时:

@{
    ViewBag.Active = "home";
    Layout = "~/Views/Shared/_Layout.cshtml";
}
Run Code Online (Sandbox Code Playgroud)

有没有比我目前使用的更好的方法来分离活动链接?

Dar*_*rov 126

更好的方法是使用HTML帮助程序:

using System.Web.Mvc; 
using System.Web.Mvc.Html;

public static class MenuExtensions
{
    public static MvcHtmlString MenuItem(
        this HtmlHelper htmlHelper, 
        string text,
        string action, 
        string controller
    )
    {
        var li = new TagBuilder("li");
        var routeData = htmlHelper.ViewContext.RouteData;
        var currentAction = routeData.GetRequiredString("action");
        var currentController = routeData.GetRequiredString("controller");
        if (string.Equals(currentAction, action, StringComparison.OrdinalIgnoreCase) &&
            string.Equals(currentController, controller, StringComparison.OrdinalIgnoreCase))
        {
            li.AddCssClass("active");
        }
        li.InnerHtml = htmlHelper.ActionLink(text, action, controller).ToHtmlString();
        return MvcHtmlString.Create(li.ToString());
    }
}
Run Code Online (Sandbox Code Playgroud)

然后:

<ul>
    @Html.MenuItem("Home", "Home", "Home")
    @Html.MenuItem("Products", "Index", "Products")
</ul>
Run Code Online (Sandbox Code Playgroud)

要完成上述工作,您需要使用视图来识别扩展:在Views文件夹中的Web.config中,<add namespace="yourNamespacehere.Helpers" />在namespaces标记内添加.然后构建项目并关闭并重新打开要添加到其中的视图.

然后根据当前操作和控制器,帮助器active在生成锚点时将添加或不添加类.

  • 谢谢你,为了澄清C#和MVC 3的新手,这就是我必须要做的事情:在root上创建Helpers文件夹,创建一个类MenuExtensions.cs,并在此文件夹中包含上述代码.在文件的顶部添加`using System.Web.Mvc;``使用System.Web.Mvc.Html;`在Views文件夹的Web.config中,添加`<add namespace ="yourNamespacehere.Helpers"/>`在名称空间标记内. (20认同)

dpe*_*ish 6

扩展Darin的例子,这里是完整的类,它为helper上的RouteValues和HtmlAttributes添加了额外的可选参数.实际上,它的行为就像基础ActionLink一样.

using System;
using System.Web.Mvc;
using System.Web.Mvc.Html;

namespace MYNAMESPACE.Helpers {
    public static class MenuExtensions {
        public static MvcHtmlString MenuItem(this HtmlHelper htmlHelper,
                                             string text, string action,
                                             string controller,
                                             object routeValues = null,
                                             object htmlAttributes = null) {
            var li = new TagBuilder("li");
            var routeData = htmlHelper.ViewContext.RouteData;
            var currentAction = routeData.GetRequiredString("action");
            var currentController = routeData.GetRequiredString("controller");
            if (string.Equals(currentAction,
                              action,
                              StringComparison.OrdinalIgnoreCase) &&
                string.Equals(currentController,
                              controller,
                              StringComparison.OrdinalIgnoreCase)) {
                li.AddCssClass("active");
            }
            if (routeValues != null) {
                li.InnerHtml = (htmlAttributes != null)
                    ? htmlHelper.ActionLink(text,
                                            action,
                                            controller,
                                            routeValues,
                                            htmlAttributes).ToHtmlString()
                    : htmlHelper.ActionLink(text, 
                                            action, 
                                            controller, 
                                            routeValues).ToHtmlString();
            }
            else {
                li.InnerHtml = htmlHelper.ActionLink(text, 
                                                     action, 
                                                     controller).ToHtmlString();
            }
            return MvcHtmlString.Create(li.ToString());
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在View文件夹的web.config中:

<system.web.webPages.razor>
  <host ... />
  <pages ... >
    <namespaces>
      ...

      ...
      <add namespace="MYNAMESPACE.Helpers" />
    </namespaces>
  </pages>
</system.web.webPages.razor>
Run Code Online (Sandbox Code Playgroud)