C#mvc从部分控制器获取带有菜单项的活动菜单项

Rob*_*Rob 2 c# asp.net-mvc html-helper asp.net-mvc-4

我正在mvc4中建立一个新网站,我正在从数据库中检索菜单动态.为了防止在每个控制器和视图中反复执行相同的操作以创建菜单,我使用具有局部视图的部分控制器来构建菜单.由于这篇文章,我已经做到了这一点.

我想要实现的下一件事是根据当前控制器和动作确定当前活动菜单项,所以我创建了一个html帮助器来执行此操作.该代码基于本文.

我的代码看起来像这样;

Partialcontroller.cs

[ChildActionOnly]
        public ActionResult MainMenu()
        {
            var viewModel = new MenuModel();

            try
            {
                IList<MenuItem> menuItems = MenuService.First(x => x.Name == "MainMenu").MenuItems;

                //Get the menuItems collection from somewhere
                if (menuItems != null && menuItems.Count > 0)
                {
                    viewModel.MenuItems = menuItems;
                    return View(viewModel);
                }
            }
            catch (Exception exception)
            {
                //TODO: Exception handling and logging
            }

            return View(viewModel);
        }
Run Code Online (Sandbox Code Playgroud)

MainMenu.cshtml

这是包含在布局中的局部视图,其中包含这段代码;

<nav class="nav-collapse collapse">
    <ul class="row-fluid nav">
        @foreach (var item in Model.MenuItems)
        {
            <li class="span2">
                @Html.MenuItem(item.Name, item.ActionName, item.ControllerName)
            </li>
        }

    </ul>
</nav>
Run Code Online (Sandbox Code Playgroud)

HtmlHelper.cs

我在部分视图中使用htmlhelper方法来构建菜单项.这是问题所在.

public static MvcHtmlString MenuItem(this HtmlHelper htmlHelper, string linkText, string actionName, string controllerName)
        {
            string currentAction = htmlHelper.ViewContext.RouteData.GetRequiredString("action");
            string currentController = htmlHelper.ViewContext.RouteData.GetRequiredString("controller");
            if (actionName == currentAction && controllerName == currentController)
            {
                return htmlHelper.ActionLink(
                    linkText,
                    actionName,
                    controllerName,
                    null,
                    new
                    {
                        @class = "active"
                    });
            }

            //var link = htmlHelper.ActionLink("<span>{LinkText}<span>", actionName, controllerName).ToHtmlString();
            //return new MvcHtmlString(link.Replace("{LinkText}", linkText));

            return htmlHelper.ActionLink(linkText, actionName, controllerName);
        }
Run Code Online (Sandbox Code Playgroud)

调试时,我看到变量'currentController'包含'Partial'值,变量'currentAction'包含'MainMenu'.所有这些对我来说都很合乎逻辑,因为这是用于构建菜单的控制器操作.但是,这也是问题所在.这两个变量将始终包含值'Partial'和'MainMenu',因为MenuItem助手总是在由PartialController实例化的视图中调用.这样我就永远无法匹配发出请求的实际控制器.

我想要做的就是,例如,单击菜单中的联系人按钮,将其视为活动菜单项.此菜单项的操作可以是ContactController的Index操作,因此如果控制器和操作与控制器匹配以及与菜单项映射的操作,则应添加其他css类.

我该怎么做才能解决这个问题?我更喜欢在代码中而不是脏javascript函数中执行此操作,但我不知道它是否可行或如何执行?

Rik*_*igh 6

我认为您可以使用htmlHelper.ViewContext上的ParentActionViewContext属性访问父控制器

string currentController = htmlHelper.ViewContext.ParentActionViewContext.RouteData.GetRequiredString("controller");
Run Code Online (Sandbox Code Playgroud)