Posted By

jmcd on 01/25/10


Tagged


Versions (?)

LinkBuilder For Areas in ASP.NET MVC2


 / 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.

  1. public static class AreaLinkBuilder
  2. {
  3. public static string BuildUrlFromExpression<TController>(RequestContext context, RouteCollection routeCollection, Expression<Action<TController>> action) where TController : Controller
  4. {
  5. var memberInfo = ExpressionMemberFinder.FindMemberOrNull(action);
  6. var targetNamespace = memberInfo.DeclaringType.Namespace;
  7.  
  8. var collection = new RouteCollection();
  9. routeCollection.Where(x =>
  10. {
  11. var route = x as Route;
  12. if (route != null)
  13. {
  14. var namespaces = route.DataTokens["Namespaces"] as string[];
  15. if (namespaces != null)
  16. {
  17. foreach (var @namespace in namespaces)
  18. {
  19. if (@namespace == targetNamespace)
  20. {
  21. return true;
  22. }
  23. }
  24. }
  25. }
  26. return false;
  27. }).ForEach(collection.Add);
  28.  
  29. var routeValues = ExpressionHelper.GetRouteValuesFromExpression(action);
  30. var vpd = collection.GetVirtualPath(context, routeValues);
  31. return (vpd == null) ? null : vpd.VirtualPath;
  32. }
  33. }
  34.  
  35.  
  36. public class ExpressionMemberFinder
  37. {
  38. public static MemberInfo FindMemberOrNull(Expression expression)
  39. {
  40. switch (expression.NodeType)
  41. {
  42. case ExpressionType.Coalesce:
  43. return FindMemberOrNull(((BinaryExpression)expression).Left) ?? FindMemberOrNull(((BinaryExpression)expression).Right);
  44. case ExpressionType.Convert:
  45. return FindMemberOrNull(((UnaryExpression)expression).Operand);
  46. case ExpressionType.Lambda:
  47. return FindMemberOrNull(((LambdaExpression)expression).Body);
  48. case ExpressionType.Call:
  49. return ((MethodCallExpression)expression).Method;
  50. case ExpressionType.MemberAccess:
  51. return ((MemberExpression)expression).Member;
  52. default:
  53. return null;
  54. }
  55. }
  56. }
  57.  
  58.  
  59. public static class ControllerExtensions
  60. {
  61. public static string ActionUrl<TController>(this Controller @this, Expression<Action<TController>> action) where TController : Controller
  62. {
  63. return AreaLinkBuilder.BuildUrlFromExpression(@this.ControllerContext.RequestContext, RouteTable.Routes, action);
  64. }
  65. }
  66.  
  67.  
  68. public static class ViewExtensions
  69. {
  70. public static string ActionUrl<TController>(this SparkView @this, Expression<Action<TController>> action) where TController : Controller
  71. {
  72. return AreaLinkBuilder.BuildUrlFromExpression(@this.ViewContext.RequestContext, RouteTable.Routes, action);
  73. }
  74. }

Report this snippet  

You need to login to post a comment.