Created
April 1, 2012 11:00
-
-
Save NOtherDev/2274614 to your computer and use it in GitHub Desktop.
Strongly typed and well-controlled links within ASP.NET MVC areas
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)] | |
public class LinkWithinAreaAttribute : Attribute | |
{ | |
public string AreaName { get; private set; } | |
public string OrSwitchTo { get; set; } | |
public LinkWithinAreaAttribute(string areaName) | |
{ | |
AreaName = areaName; | |
} | |
} | |
public static class LinkWithinArea | |
{ | |
public static RouteValueDictionary FixArea<TController>(this RouteValueDictionary routeValues) | |
{ | |
var attr = (LinkWithinAreaAttribute) typeof(TController) | |
.GetCustomAttributes(typeof(LinkWithinAreaAttribute), inherit: true) | |
.SingleOrDefault(); | |
if (attr != null && !IsInAlternativeArea(routeValues, attr)) | |
routeValues["area"] = attr.AreaName; | |
return routeValues; | |
} | |
private static bool IsInAlternativeArea(RouteValueDictionary routeValues, LinkWithinAreaAttribute attr) | |
{ | |
return attr.OrSwitchTo != null | |
&& routeValues.ContainsKey("area") | |
&& attr.OrSwitchTo.ToLowerInvariant() == routeValues["area"].ToString().ToLowerInvariant(); | |
} | |
} | |
public static class AreaAwareLinkingExtensions | |
{ | |
public static string Action<TController>(this UrlHelper helper, Expression<Action<TController>> action) | |
where TController : Controller | |
{ | |
var vpd = helper.RouteCollection | |
.GetVirtualPathForArea(helper.RequestContext, GetFixedRouteValues(action)); | |
return (vpd == null) ? null : vpd.VirtualPath; | |
} | |
public static void RenderAction<TController>(this HtmlHelper helper, Expression<Action<TController>> action) | |
where TController : Controller | |
{ | |
var routeValues = GetFixedRouteValues(action); | |
foreach (var keyValuePair in helper.ViewContext.RouteData.Values) | |
{ | |
if (!routeValues.ContainsKey(keyValuePair.Key)) | |
routeValues.Add(keyValuePair.Key, keyValuePair.Value); | |
} | |
helper.RenderRoute(routeValues); | |
} | |
public static MvcHtmlString ActionLink<TController>(this HtmlHelper helper, Expression<Action<TController>> action, string linkText, object htmlAttributes = null) | |
where TController : Controller | |
{ | |
return System.Web.Mvc.Html.LinkExtensions.RouteLink(helper, linkText, GetFixedRouteValues(action), new RouteValueDictionary(htmlAttributes)); | |
} | |
private static RouteValueDictionary GetFixedRouteValues<TController>(Expression<Action<TController>> action) | |
where TController : Controller | |
{ | |
return Microsoft.Web.Mvc.Internal.ExpressionHelper.GetRouteValuesFromExpression(action).FixArea<TController>(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment