6
\$\begingroup\$

I'm using this technique for highlighting current links (e.g. how the "Questions" link is highlighted on this very page you're looking at). I changed the code a little bit and came up with this extension method:

 public static MvcHtmlString MenuLink(
 this HtmlHelper helper,
 string content, string action, string controller)
 {
 var routeData = helper.ViewContext.RouteData.Values;
 var currentController = routeData["controller"];
 var currentAction = routeData["action"];
 var builder = new TagBuilder("li")
 {
 InnerHtml = content
 };
 if (String.Equals(action, currentAction as string,
 StringComparison.OrdinalIgnoreCase)
 &&
 String.Equals(controller, currentController as string,
 StringComparison.OrdinalIgnoreCase))
 {
 builder.AddCssClass("active");
 return MvcHtmlString.Create(builder.ToString());
 }
 return MvcHtmlString.Create(builder.ToString());
 }

It works fine, But that’s some ugly code. I use the extension method this way:

@Html.MenuLink("<a href=" + @Url.Action("MainPage", "Ticket") + "><i class='fa fa-fw fa-home'></i>Ticket Page</a>", "MainPage", "Ticket")

As you can see, part of that isn't strongly typed.

Do you have any ideas to improve the extension method?

BCdotWEB
11.4k2 gold badges28 silver badges45 bronze badges
asked Sep 23, 2015 at 14:11
\$\endgroup\$
0

1 Answer 1

2
\$\begingroup\$

One thing that I see that I would change is the if statement

 if (String.Equals(action, currentAction as string,
 StringComparison.OrdinalIgnoreCase)
 &&
 String.Equals(controller, currentController as string,
 StringComparison.OrdinalIgnoreCase))
 {
 builder.AddCssClass("active");
 return MvcHtmlString.Create(builder.ToString());
 }

I personally don't like having a conditional that spans over multiple lines, so the first thing that I would do is to take the boolean conditions and make them into boolean variables and then use them inside the conditional. I think it would be easier to read.

bool isCurrentAction = String.Equals(action, currentAction as string,
 StringComparison.OrdinalIgnoreCase);
bool isCurrentController = String.Equals(controller, currentController as string,
 StringComparison.OrdinalIgnoreCase);
if (isCurrentAction && isCurrentController)
{
 builder.AddCssClass("active");
 return MvcHtmlString.Create(builder.ToString());
}

And since you are returning builder immediately after the if statement, there isn't really a reason to return inside the if statement, it is rather redundant. Just delete that from the if block

bool isCurrentAction = String.Equals(action, currentAction as string,
 StringComparison.OrdinalIgnoreCase);
bool isCurrentController = String.Equals(controller, currentController as string,
 StringComparison.OrdinalIgnoreCase);
if (isCurrentAction && isCurrentController)
{
 builder.AddCssClass("active");
}
answered Sep 23, 2015 at 14:55
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.