1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181
|
/* ****************************************************************************
*
* Copyright (c) Microsoft Corporation. All rights reserved.
*
* This software is subject to the Microsoft Public License (Ms-PL).
* A copy of the license can be found in the license.htm file included
* in this distribution.
*
* You must not remove this notice, or any other, from this software.
*
* ***************************************************************************/
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;
}
}
}
}
|