Here is how I solved this in MVC 2:
/// <summary>
/// Creates an anchor tag based on the passed in controller type and method.
/// Does NOT encode passed in link text.
/// </summary>
/// <typeparam name="TController">The controller type</typeparam>
/// <param name="htmlHelper">The HTML helper</param>
/// <param name="action">The method to route to</param>
/// <param name="linkText">The linked text to appear on the page</param>
/// <returns>A formatted anchor tag</returns>
public static MvcHtmlString ActionLink<TController>( this HtmlHelper htmlHelper,
Expression<Action<TController>> action,
HtmlString linkText ) where TController : Controller
{
return ActionLink( htmlHelper, action, linkText, null, null );
}
/// <summary>
/// Creates an anchor tag based on the passed in controller type and method.
/// Does NOT encode passed in link text.
/// </summary>
/// <typeparam name="TController">The controller type</typeparam>
/// <param name="htmlHelper">The HTML helper</param>
/// <param name="action">The method to route to</param>
/// <param name="linkText">The linked text to appear on the page</param>
/// <param name="routeValues">The route values</param>
/// <param name="htmlAttributes">The HTML attributes</param>
/// <returns>A formatted anchor tag</returns>
public static MvcHtmlString ActionLink<TController>( this HtmlHelper htmlHelper,
Expression<Action<TController>> action,
HtmlString linkText,
object routeValues,
object htmlAttributes ) where TController : Controller
{
var routingValues = GetRouteValuesFromExpression( action, routeValues );
var url = UrlHelper.GenerateUrl( null, //routeName
null, //actionName
null, //controllerName
routingValues,
htmlHelper.RouteCollection,
htmlHelper.ViewContext.RequestContext,
false ); //includeImplicitMvcValues
var tagBuilder = new TagBuilder("a")
{
InnerHtml = !String.IsNullOrEmpty( linkText.ToString() ) ? linkText.ToString() : String.Empty
};
tagBuilder.MergeAttributes( (IDictionary<string, object>)htmlAttributes );
tagBuilder.MergeAttribute( "href", url );
return MvcHtmlString.Create( tagBuilder.ToString( TagRenderMode.Normal ) );
}
It is strongly typed, as in the MVC futures NuGet package. So you can use it like this:
<%= Html.ActionLink<HomeController>( x => x.Index(),
new HtmlString( "Don't Encode Me!<sup>®</sup>" ) ) %>