In ASP.NET MVC 2 – How do I get Route Values into my navigation controller so I can highlight the current link?

I’m trying to get the current Route into my navigation controller so I can run comparisons as the navigation menu data is populated.

My Links object is like this:

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

In the master page, I’m trying to pass the current route to the nav controller like this:

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

The problem that I’m running into is that I can’t figure out how to get any of the data out of currentRoute. What is the best technique for getting the values out or currentRoute?

I’ve tried syntax like this:

 currentRoute.Values.routevaluename

and

 currentRoute.Values[0]

But I can’t seem to get it to work.

Edit

I have also tried placing this code into the action of the navigation controller:

var current = RouteData["streamUrl"];

and

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

Both versions give me this error:

Error 1 Cannot apply indexing with [] to an expression of >type ‘System.Web.Routing.RouteData’ C:pathtocontrollerNavController.cs 25 27

Edit 2

It also might be helpful to know the route values that I’m trying to match against:

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

So, ultimately mydomain.com/blog/blogentry1 would map to the same controller/action as mydomain.com/pages/welcome. I’m not looking for the controller value or the action value, rather I’m looking for streamUrl value and EntryUrl value.

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

You don’t need to pass route data to a controller because the controller already has knowledge of it via the RouteData property:

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

Now if you want to pass some simple arguments like current action that was used to render the view you could do this:

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

And in your controller:

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

Method 2

Taken from this good article.

Create a custom extension method:

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

Your HTML markup:

<div id="menucontainer">

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

</div>

Produces the following output:

<div id="menucontainer">

    <ul id="menu">
        <li class="selected"><a href="/" rel="nofollow noreferrer noopener">Home</a></li>
        <li><a href="/Home/About" rel="nofollow noreferrer noopener">About</a></li>
    </ul>

</div>

Method 3

Here’s a sample method we wrote for doing something similar.

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


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x