ASP.NET MVC Razor动态菜单<li class =“current”> </li>

时间:2015-02-17 15:21:38

标签: asp.net-mvc razor html-helper

我有一个HTML菜单,我在共享PartialView中呈现为Layout.cshtml,并具有以下结构:

我在Layout.cshtml中调用了这样的菜单:

 @Html.Action("LeftMenu", "Common", new { context = ViewContext})

这是左侧菜单结构:

<li class='current'>
   <a class='current' href="@Url.Action("Index","Home")">
   <span class="badge pull-right">17</span>
   <i class="icon-dashboard"></i> Dashboard
   </a>
</li>
<li>
   <a href="@Url.Action("Absence","Incident")" class="is-dropdown-menu">
   <span class="badge pull-right"></span>
   <i class="icon-bar-chart"></i> Absence List
   </a>
   <ul>
      <li>
         <a href="@Url.Action("AbsenceList","Incident")">
         <i class="icon-random"></i>
         Notice List
         </a>
      </li>
      <li>
         <a href="@Url.Action("NewAbsence","Incident")">
         <i class="icon-bullseye"></i>
         New Notice
         </a>
      </li>
   </ul>
</li>

我希望根据当前视图使我的链接动态化我可以通过分配<li>以及class='current'元素来激活<a href>元素。

我看到我可以使用HTML Helper来做到这一点:

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());
    }

但上面的代码我不认为它会帮助我创建我的菜单所需的确切<li>结构,以便看起来不错。

enter image description here

如果我检查(谷歌浏览器)我的活动菜单元素我得到的是:

enter image description here

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:2)

可以修改助手以生成您寻求的输出

public static MvcHtmlString MenuItem(this HtmlHelper htmlHelper, string text, string action, string controller, string num, string icon)
{
    var routeData = htmlHelper.ViewContext.RouteData;
    var currentAction = routeData.GetRequiredString("action");
    var currentController = routeData.GetRequiredString("controller");
    bool isCurrent = string.Equals(currentAction, action, StringComparison.OrdinalIgnoreCase) && string.Equals(currentController, controller, StringComparison.OrdinalIgnoreCase);
    UrlHelper urlHelper = new UrlHelper(htmlHelper.ViewContext.RequestContext);
    string url = urlHelper.Action(action, controller);
    StringBuilder html = new StringBuilder();
    TagBuilder span = new TagBuilder("span");
    span.AddCssClass("badge pull-right");
    span.InnerHtml = num;
    html.Append(span);
    TagBuilder i = new TagBuilder("i");
    i.AddCssClass(icon);
    html.Append(i);
    span = new TagBuilder("span");
    span.InnerHtml = text;
    html.Append(span);
    TagBuilder a = new TagBuilder("a");
    a.MergeAttribute("href", url);
    if (isCurrent)
    {
        a.AddCssClass("current");
    }
    a.InnerHtml = html.ToString();
    TagBuilder li = new TagBuilder("li");
    if (isCurrent)
    {
        li.AddCssClass("current");
    }
    li.InnerHtml = a.ToString();
    return MvcHtmlString.Create(li.ToString());
}

并在视图中将其用作

@Html.MenuItem("Dashboard", "Index", "Home", "17", "icon-dashboard")

答案 1 :(得分:0)

我通常会做以下事情:

@{ string url; }
<ul>
    @{ url = Url.Action("SomeAction", "SomeController"); }
    <li>
        <a class="@(url == Request.Url.AbsolutePath ? "current" : string.Empty)" href="@url">
            Some Action
        </a>
    </li>

    @{ url = Url.Action("SomeOtherAction", "SomeOtherController"); }
    <li>
        <a class="@(url == Request.Url.AbsolutePath ? "current" : string.Empty)" href="@url">
            Some Other Action
        </a>
    </li>

    ...

换句话说,在每种情况下,您将链接的URL与当前请求的URL进行比较,并在匹配时呈现该类。