/ Published in: C#
The LinkBuilder implementation provided with the MVC Futures assembly does not work with areas. This re-implementation matches routes with areas via declared namespaces.
Expand |
Embed | Plain Text
Copy this code and paste it in your HTML
public static class AreaLinkBuilder { public static string BuildUrlFromExpression<TController>(RequestContext context, RouteCollection routeCollection, Expression<Action<TController>> action) where TController : Controller { var memberInfo = ExpressionMemberFinder.FindMemberOrNull(action); var targetNamespace = memberInfo.DeclaringType.Namespace; routeCollection.Where(x => { var route = x as Route; if (route != null) { var namespaces = route.DataTokens["Namespaces"] as string[]; if (namespaces != null) { foreach (var @namespace in namespaces) { if (@namespace == targetNamespace) { return true; } } } } return false; }).ForEach(collection.Add); var routeValues = ExpressionHelper.GetRouteValuesFromExpression(action); var vpd = collection.GetVirtualPath(context, routeValues); return (vpd == null) ? null : vpd.VirtualPath; } } public class ExpressionMemberFinder { public static MemberInfo FindMemberOrNull(Expression expression) { switch (expression.NodeType) { case ExpressionType.Coalesce: return FindMemberOrNull(((BinaryExpression)expression).Left) ?? FindMemberOrNull(((BinaryExpression)expression).Right); case ExpressionType.Convert: return FindMemberOrNull(((UnaryExpression)expression).Operand); case ExpressionType.Lambda: return FindMemberOrNull(((LambdaExpression)expression).Body); case ExpressionType.Call: return ((MethodCallExpression)expression).Method; case ExpressionType.MemberAccess: return ((MemberExpression)expression).Member; default: return null; } } } public static class ControllerExtensions { public static string ActionUrl<TController>(this Controller @this, Expression<Action<TController>> action) where TController : Controller { return AreaLinkBuilder.BuildUrlFromExpression(@this.ControllerContext.RequestContext, RouteTable.Routes, action); } } public static class ViewExtensions { public static string ActionUrl<TController>(this SparkView @this, Expression<Action<TController>> action) where TController : Controller { return AreaLinkBuilder.BuildUrlFromExpression(@this.ViewContext.RequestContext, RouteTable.Routes, action); } }