I am working on an application using MVC and discovered quite quickly that there is no documented way to control my main menu’s looks while it is in the master page. After searching for an hour or more I knew there had to be a way to overcome this without resorting to adding a code-behind file.
I found a couple of java-script solutions but wanted something more robust. I queried out to several tech lists, including my favorite on http://aspadvice.com/lists and got some quick hits back. I think my favorite was “extension methods are your friend. :)”. Thanks Paul – I’ve never used Extension Methods.
So, on to Extension Methods – which are wickedly cool! MSDN says this about Extension Methods:
Extension methods enable you to "add" methods to existing types without creating a new derived type, recompiling, or otherwise modifying the original type. Extension methods are a special kind of static method, but they are called as if they were instance methods on the extended type. For client code written in C# and Visual Basic, there is no apparent difference between calling an extension method and the methods that are actually defined in a type.
So, after a couple of false starts and a few blog entries that were semi-complete I finally have my first Extension Method working! It is not very clean yet so feel free to suggest ways to make this code block better:
using System;
using System.Web;
namespace System.Web
{
public static class HtmlExtensions
{
public static string GetSelected(this HttpRequest Request, string id, string target)
{
if (target.ToUpper().IndexOf(Request.Url.ToString().ToUpper()) > 0)
id += "active";
return id;
}
}
}
To use this I am twiddling the ID attribute on my <LI> elements. The CSS uses a PNG image with offsets (a sprite I believe it is called) and is looking for either the CSS tag of navA or navAactive. So, in my code for my menu bar I now have this:
div id="main_nav">
<ul>
<li id="<%= Request.GetSelected("navA", "") %>"><%= Html.ActionLink(" ", "Index", "Home")%></li>
<li id="<%= Request.GetSelected("navB", "Product") %>"><%= Html.ActionLink(" ", "Index", "Product")%></li>
</ul>
</div>
Now, depending on what URL is being passed through the Master Page the Extension Method will pull out the URL from the Request object (which is the object we are extending), check to see if the target is in the string. and if it is, append the active token to the id that was passed in. Obviously this is a site specific Method Extension so I added it to a folder called libraries under my MVC app directory. I also changed the namespace to System.Web so I don’t need to prefix it when I use it, nor do I have to add a reference for it in any page.
Comments?