views:

48

answers:

1

I am writing a helper for my application which writes out a menu item for a given strongly typed controller/action as follows:

<%= Html.MenuLink<WhateverController>(c => c.WhateverAction(), "Whatever") %>

As part of this process, I would like to apply the class of active to the outputted link if the current page and the page linked to are the same. I figure the best way of doing it is to compare the contents of the RouteValueDictionary for the current request to that of the result of the Expression given to the helper method. However, I cannot figure out a good way of comparing whether the items in the two RouteValueDictionarys are the same.

Is there a simple way of doing this? I effectively want to complete it in the following way:

public static string MenuLink<T>(this HtmlHelper html, Expression<Action<T>> action, string linkText) where T : Controller
{
    // var link = html.ActionLink<T>(action, linkText, new {}); // Not important yet

    var routeValues = Microsoft.Web.Mvc.Internal.ExpressionHelper.GetRouteValuesFromExpression<T>(action);  // Might change?
    var currentRouteVals = html.ViewContext.RouteData.Values;
    bool isActivePage = /* are the contents of routeValues also 
                           inside currentRouteValues? */

    var tb = new TagBuilder("li");
    // Continues...
}

I have tried using the built-in comparison (==), but it seems that it is using the default equality implementation and therefore returns false since they are not the same instance. I have also tried the following:

bool isActivePage = routeValues.All(x => currentRouteVals.ContainsValue(x));

but that doesn't work either. Am I completely barking up the wrong tree?

A: 

Bah, I post the question and then figure out the answer. Am posting here in case anyone else faces this problem. The line I needed was as follows:

bool isActivePage = routeValues.All(x => x.Value.ToString() == (currentRouteVals[x.Key].ToString()));

Turns out it was originally comparing them as objects, not as strings. Converting them to strings compares them as one would hope, and now all is well.

It should be noted that they should be compared around this way. If they are compared round the other way, the RouteValueDictionary may contain things other than those you care about (such as an "id" value). Or at least that's how I understand it at the moment. Further experimentation may require me to revisit this...

Splash