【问题标题】:C# mvc get active menu item with menu items from partial controllerC# mvc 从部分控制器获取带有菜单项的活动菜单项
【发布时间】:2013-07-16 14:06:02
【问题描述】:

我正在 mvc4 中建立一个新网站,我正在从数据库中检索菜单动态。为了防止在每个控制器和视图中一遍又一遍地执行相同的操作来创建菜单,我使用带有部分视图的部分控制器来构建菜单。感谢this 文章,我做到了。

接下来我要实现的是根据当前控制器和操作确定当前活动菜单项,因此我创建了一个 html 帮助程序来执行此操作。代码基于this article

我的代码是这样的;

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

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>

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

调试时,我看到变量“currentController”包含值“Partial”,变量“currentAction”包含“MainMenu”。一切对我来说似乎都很合乎逻辑,因为这是用于构建菜单的控制器操作。 然而,这也是问题所在。这两个变量将始终包含值“Partial”和“MainMenu”,因为 MenuItem 帮助程序始终在由 PartialController 实例化的视图中调用。这样我永远无法匹配发出请求的实际控制器。

我要做的就是,例如单击菜单中的联系人按钮并将其视为活动菜单项。这个菜单项的动作可以是 ContactController 的 Index 动作,所以如果控制器和动作与控制器匹配并且动作映射到菜单项,则应该添加一个额外的 css 类。

我能做些什么来解决这个问题?我更喜欢用代码而不是肮脏的javascript函数来做,但我不知道这是否可能或如何做?

【问题讨论】:

    标签: c# asp.net-mvc asp.net-mvc-4 html-helper


    【解决方案1】:

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

    string currentController = htmlHelper.ViewContext.ParentActionViewContext.RouteData.GetRequiredString("controller");
    

    【讨论】:

    • 我怎么没想到……希望一切都这么简单!这就像一个魅力:)
    猜你喜欢
    • 2012-01-01
    • 2021-01-27
    • 1970-01-01
    • 2013-09-14
    • 2013-10-01
    • 2011-09-24
    • 2013-03-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多