在ASP.NET MVC 2中 - 如何将路由值导入导航控制器,以便突出显示当前链接?

时间:2010-09-07 15:57:01

标签: asp.net asp.net-mvc asp.net-mvc-2 routing

我正在尝试将当前路径导入我的导航控制器,以便在填充导航菜单数据时运行比较。

我的链接对象是这样的:

public class StreamNavLinks
{
    public string Text { get; set; }
    public RouteValueDictionary RouteValues { get; set; }
    public bool IsSelected { get; set; }
}

在母版页中,我正在尝试将当前路径传递给导航控制器,如下所示:

<% Html.RenderAction(
    "MenuOfStreamEntries", // action
    "Nav", // controller
    new { // parameters for action
        currentStreamUrl = "Blog", 
        currentRoute = ViewContext.RouteData } // get route data to compare in controller
); %>

我遇到的问题是我无法弄清楚如何从currentRoute中获取任何数据。获取值的最佳方法是什么?currentRoute

我尝试过这样的语法:

 currentRoute.Values.routevaluename

 currentRoute.Values[0]

但我似乎无法让它发挥作用。

修改

我也尝试将此代码放入导航控制器的操作中:

var current = RouteData["streamUrl"];

var current = this.RouteData["streamUrl"];

两个版本都给我这个错误:

  

错误1无法将带有[]的索引应用于&gt;类型'System.Web.Routing.RouteData'的表达式C:\ pathtocontroller \ NavController.cs 25 27

编辑2

了解我想要匹配的路线值可能会有所帮助:

        routes.MapRoute(null, "", // Only matches the empty URL (i.e. ~/)
                        new
                        {
                            controller = "Stream",
                            action = "Entry",
                            streamUrl = "Pages",
                            entryUrl = "HomePage"
                        }
        );

        routes.MapRoute(null, "{streamUrl}/{entryUrl}", // matches ~/Pages/HomePage
                        new { controller = "Stream", action = "Entry" }
        );

因此,最终mydomain.com/blog/blogentry1将映射到与mydomain.com/pages/welcome相同的控制器/操作。我不是在寻找控制器值或动作值,而是在寻找streamUrl值和EntryUrl值。

3 个答案:

答案 0 :(得分:13)

您不需要将路由数据传递给控制器​​,因为控制器已通过RouteData属性了解它:

public ActionResult Index() {
    // You could use this.RouteData here
    ...
}

现在,如果你想传递一些简单的参数,比如用于渲染视图的当前动作,你可以这样做:

<%= Html.RenderAction(
    "MenuOfStreamEntries",
    "Nav",
    new {
        currentStreamUrl = "Blog", 
        currentAction = ViewContext.RouteData.Values["action"],
        currentController = ViewContext.RouteData.Values["controller"]
    }
); %>

在你的控制器中:

public ActionResult Nav(string currentAction, string currentController) 
{
    ...
}

答案 1 :(得分:4)

取自this good article

创建自定义扩展方法:

public static class HtmlExtensions
{
    public static MvcHtmlString ActionMenuItem(this HtmlHelper htmlHelper, String linkText,
        String actionName, String controllerName)
    {
        var tag = new TagBuilder("li");

        if ( htmlHelper.ViewContext.RequestContext
            .IsCurrentRoute(null, controllerName, actionName) )
        {
            tag.AddCssClass("selected");
        }

        tag.InnerHtml = htmlHelper.ActionLink(linkText, actionName, controllerName).ToString();

        return MvcHtmlString.Create(tag.ToString());
    }
}

您的HTML标记:

<div id="menucontainer">

    <ul id="menu">
        <%= Html.ActionMenuItem("Home", "Index", "Home") %>
        <%= Html.ActionMenuItem("About", "About", "Home") %>
    </ul>

</div>

产生以下输出:

<div id="menucontainer">

    <ul id="menu">
        <li class="selected"><a href="/">Home</a></li>
        <li><a href="/Home/About">About</a></li>
    </ul>

</div>

答案 2 :(得分:1)

这是我们为做类似事情而编写的示例方法。

public static bool IsCurrentAction(this HtmlHelper helper, string actionName, string controllerName)
{
  string currentControllerName = (string)helper.ViewContext.RouteData.Values["controller"];
  string currentActionName = (string)helper.ViewContext.RouteData.Values["action"];

  return currentControllerName.Equals(controllerName, StringComparison.CurrentCultureIgnoreCase) && currentActionName.Equals(actionName, StringComparison.CurrentCultureIgnoreCase));
}