a575963da9
Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
162 lines
8.1 KiB
C#
162 lines
8.1 KiB
C#
namespace System.Web.Mvc {
|
|
using System;
|
|
using System.Diagnostics.CodeAnalysis;
|
|
using System.Web.Routing;
|
|
|
|
public static class RouteCollectionExtensions {
|
|
|
|
// This method returns a new RouteCollection containing only routes that matched a particular area.
|
|
// The Boolean out parameter is just a flag specifying whether any registered routes were area-aware.
|
|
private static RouteCollection FilterRouteCollectionByArea(RouteCollection routes, string areaName, out bool usingAreas) {
|
|
if (areaName == null) {
|
|
areaName = String.Empty;
|
|
}
|
|
|
|
usingAreas = false;
|
|
RouteCollection filteredRoutes = new RouteCollection();
|
|
|
|
using (routes.GetReadLock()) {
|
|
foreach (RouteBase route in routes) {
|
|
string thisAreaName = AreaHelpers.GetAreaName(route) ?? String.Empty;
|
|
usingAreas |= (thisAreaName.Length > 0);
|
|
if (String.Equals(thisAreaName, areaName, StringComparison.OrdinalIgnoreCase)) {
|
|
filteredRoutes.Add(route);
|
|
}
|
|
}
|
|
}
|
|
|
|
// if areas are not in use, the filtered route collection might be incorrect
|
|
return (usingAreas) ? filteredRoutes : routes;
|
|
}
|
|
|
|
public static VirtualPathData GetVirtualPathForArea(this RouteCollection routes, RequestContext requestContext, RouteValueDictionary values) {
|
|
return GetVirtualPathForArea(routes, requestContext, null /* name */, values);
|
|
}
|
|
|
|
public static VirtualPathData GetVirtualPathForArea(this RouteCollection routes, RequestContext requestContext, string name, RouteValueDictionary values) {
|
|
bool usingAreas; // don't care about this value
|
|
return GetVirtualPathForArea(routes, requestContext, name, values, out usingAreas);
|
|
}
|
|
|
|
internal static VirtualPathData GetVirtualPathForArea(this RouteCollection routes, RequestContext requestContext, string name, RouteValueDictionary values, out bool usingAreas) {
|
|
if (routes == null) {
|
|
throw new ArgumentNullException("routes");
|
|
}
|
|
|
|
if (!String.IsNullOrEmpty(name)) {
|
|
// the route name is a stronger qualifier than the area name, so just pipe it through
|
|
usingAreas = false;
|
|
return routes.GetVirtualPath(requestContext, name, values);
|
|
}
|
|
|
|
string targetArea = null;
|
|
if (values != null) {
|
|
object targetAreaRawValue;
|
|
if (values.TryGetValue("area", out targetAreaRawValue)) {
|
|
targetArea = targetAreaRawValue as string;
|
|
}
|
|
else {
|
|
// set target area to current area
|
|
if (requestContext != null) {
|
|
targetArea = AreaHelpers.GetAreaName(requestContext.RouteData);
|
|
}
|
|
}
|
|
}
|
|
|
|
// need to apply a correction to the RVD if areas are in use
|
|
RouteValueDictionary correctedValues = values;
|
|
RouteCollection filteredRoutes = FilterRouteCollectionByArea(routes, targetArea, out usingAreas);
|
|
if (usingAreas) {
|
|
correctedValues = new RouteValueDictionary(values);
|
|
correctedValues.Remove("area");
|
|
}
|
|
|
|
VirtualPathData vpd = filteredRoutes.GetVirtualPath(requestContext, correctedValues);
|
|
return vpd;
|
|
}
|
|
|
|
[SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "1#", Justification = "This is not a regular URL as it may contain special routing characters.")]
|
|
public static void IgnoreRoute(this RouteCollection routes, string url) {
|
|
IgnoreRoute(routes, url, null /* constraints */);
|
|
}
|
|
|
|
[SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "1#", Justification = "This is not a regular URL as it may contain special routing characters.")]
|
|
public static void IgnoreRoute(this RouteCollection routes, string url, object constraints) {
|
|
if (routes == null) {
|
|
throw new ArgumentNullException("routes");
|
|
}
|
|
if (url == null) {
|
|
throw new ArgumentNullException("url");
|
|
}
|
|
|
|
IgnoreRouteInternal route = new IgnoreRouteInternal(url) {
|
|
Constraints = new RouteValueDictionary(constraints)
|
|
};
|
|
|
|
routes.Add(route);
|
|
}
|
|
|
|
[SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "2#", Justification = "This is not a regular URL as it may contain special routing characters.")]
|
|
public static Route MapRoute(this RouteCollection routes, string name, string url) {
|
|
return MapRoute(routes, name, url, null /* defaults */, (object)null /* constraints */);
|
|
}
|
|
|
|
[SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "2#", Justification = "This is not a regular URL as it may contain special routing characters.")]
|
|
public static Route MapRoute(this RouteCollection routes, string name, string url, object defaults) {
|
|
return MapRoute(routes, name, url, defaults, (object)null /* constraints */);
|
|
}
|
|
|
|
[SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "2#", Justification = "This is not a regular URL as it may contain special routing characters.")]
|
|
public static Route MapRoute(this RouteCollection routes, string name, string url, object defaults, object constraints) {
|
|
return MapRoute(routes, name, url, defaults, constraints, null /* namespaces */);
|
|
}
|
|
|
|
[SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "2#", Justification = "This is not a regular URL as it may contain special routing characters.")]
|
|
public static Route MapRoute(this RouteCollection routes, string name, string url, string[] namespaces) {
|
|
return MapRoute(routes, name, url, null /* defaults */, null /* constraints */, namespaces);
|
|
}
|
|
|
|
[SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "2#", Justification = "This is not a regular URL as it may contain special routing characters.")]
|
|
public static Route MapRoute(this RouteCollection routes, string name, string url, object defaults, string[] namespaces) {
|
|
return MapRoute(routes, name, url, defaults, null /* constraints */, namespaces);
|
|
}
|
|
|
|
[SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "2#", Justification = "This is not a regular URL as it may contain special routing characters.")]
|
|
public static Route MapRoute(this RouteCollection routes, string name, string url, object defaults, object constraints, string[] namespaces) {
|
|
if (routes == null) {
|
|
throw new ArgumentNullException("routes");
|
|
}
|
|
if (url == null) {
|
|
throw new ArgumentNullException("url");
|
|
}
|
|
|
|
Route route = new Route(url, new MvcRouteHandler()) {
|
|
Defaults = new RouteValueDictionary(defaults),
|
|
Constraints = new RouteValueDictionary(constraints),
|
|
DataTokens = new RouteValueDictionary()
|
|
};
|
|
|
|
if ((namespaces != null) && (namespaces.Length > 0)) {
|
|
route.DataTokens["Namespaces"] = namespaces;
|
|
}
|
|
|
|
routes.Add(name, route);
|
|
|
|
return route;
|
|
}
|
|
|
|
private sealed class IgnoreRouteInternal : Route {
|
|
public IgnoreRouteInternal(string url)
|
|
: base(url, new StopRoutingHandler()) {
|
|
}
|
|
|
|
public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary routeValues) {
|
|
// Never match during route generation. This avoids the scenario where an IgnoreRoute with
|
|
// fairly relaxed constraints ends up eagerly matching all generated URLs.
|
|
return null;
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|