diff --git a/src/System.Web.Compatibility/NotSupported.Exclude.txt b/src/System.Web.Compatibility/NotSupported.Exclude.txt
index 04797e4eb..d8bd9fb39 100644
--- a/src/System.Web.Compatibility/NotSupported.Exclude.txt
+++ b/src/System.Web.Compatibility/NotSupported.Exclude.txt
@@ -5,3 +5,7 @@ T:System.Web.HttpUtility
P:System.Web.HttpContext.Current
P:System.Web.Hosting.HostingEnvironment.IsHosted
P:System.Web.Hosting.HostingEnvironment.SiteName
+T:System.Web.Routing.RequestContext
+T:System.Web.Routing.RouteData
+T:System.Web.Routing.RouteValueDictionary
+T:System.Web.Routing.StopRoutingHandler
diff --git a/src/System.Web.Compatibility/Strings.Designer.cs b/src/System.Web.Compatibility/Strings.Designer.cs
index 124559871..7ceb5ec48 100644
--- a/src/System.Web.Compatibility/Strings.Designer.cs
+++ b/src/System.Web.Compatibility/Strings.Designer.cs
@@ -68,5 +68,14 @@ namespace System.Web {
return ResourceManager.GetString("PlatformNotSupportedSystemWeb", resourceCulture);
}
}
+
+ ///
+ /// Looks up a localized string similar to The RouteData must contain an item named '{0}' with a non-empty string value..
+ ///
+ internal static string RouteData_RequiredValue {
+ get {
+ return ResourceManager.GetString("RouteData_RequiredValue", resourceCulture);
+ }
+ }
}
}
diff --git a/src/System.Web.Compatibility/Strings.resx b/src/System.Web.Compatibility/Strings.resx
index d3854a644..a8b3f4e3c 100644
--- a/src/System.Web.Compatibility/Strings.resx
+++ b/src/System.Web.Compatibility/Strings.resx
@@ -120,4 +120,7 @@
System.Web is not supported on this platform
+
+ The RouteData must contain an item named '{0}' with a non-empty string value.
+
\ No newline at end of file
diff --git a/src/System.Web.Compatibility/System/Web/Routing/RequestContext.cs b/src/System.Web.Compatibility/System/Web/Routing/RequestContext.cs
new file mode 100644
index 000000000..5cd735f0b
--- /dev/null
+++ b/src/System.Web.Compatibility/System/Web/Routing/RequestContext.cs
@@ -0,0 +1,24 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Runtime.CompilerServices;
+
+namespace System.Web.Routing
+{
+ [TypeForwardedFrom("System.Web.Routing, Version=3.5.0.0, Culture=Neutral, PublicKeyToken=31bf3856ad364e35")]
+ public class RequestContext
+ {
+ public RequestContext() { }
+
+ public RequestContext(HttpContextBase httpContext, RouteData routeData)
+ {
+ HttpContext = httpContext ?? throw new ArgumentNullException(nameof(httpContext));
+ RouteData = routeData ?? throw new ArgumentNullException(nameof(routeData));
+ }
+
+ public virtual HttpContextBase HttpContext { get; set; }
+
+ public virtual RouteData RouteData { get; set; }
+ }
+}
diff --git a/src/System.Web.Compatibility/System/Web/Routing/RouteData.cs b/src/System.Web.Compatibility/System/Web/Routing/RouteData.cs
new file mode 100644
index 000000000..54217b0d3
--- /dev/null
+++ b/src/System.Web.Compatibility/System/Web/Routing/RouteData.cs
@@ -0,0 +1,45 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Globalization;
+using System.Runtime.CompilerServices;
+
+namespace System.Web.Routing {
+
+ [TypeForwardedFrom("System.Web.Routing, Version=3.5.0.0, Culture=Neutral, PublicKeyToken=31bf3856ad364e35")]
+ public class RouteData {
+ public RouteData() { }
+
+ public RouteData(RouteBase route, IRouteHandler routeHandler) {
+ Route = route;
+ RouteHandler = routeHandler;
+ }
+
+ public RouteValueDictionary DataTokens { get; } = new RouteValueDictionary();
+
+ public RouteBase Route { get; set; }
+
+ public IRouteHandler RouteHandler { get; set; }
+
+ public RouteValueDictionary Values { get; } = new RouteValueDictionary();
+
+ public string GetRequiredString(string valueName)
+ {
+ if (Values.TryGetValue(valueName, out object value))
+ {
+ string valueString = value as string;
+ if (!string.IsNullOrEmpty(valueString))
+ {
+ return valueString;
+ }
+ }
+
+ throw new InvalidOperationException(
+ string.Format(
+ CultureInfo.CurrentUICulture,
+ Strings.RouteData_RequiredValue,
+ valueName));
+ }
+ }
+}
diff --git a/src/System.Web.Compatibility/System/Web/Routing/RouteValueDictionary.cs b/src/System.Web.Compatibility/System/Web/Routing/RouteValueDictionary.cs
new file mode 100644
index 000000000..a475eea6d
--- /dev/null
+++ b/src/System.Web.Compatibility/System/Web/Routing/RouteValueDictionary.cs
@@ -0,0 +1,182 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Collections;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Runtime.CompilerServices;
+
+namespace System.Web.Routing
+{
+ [TypeForwardedFrom("System.Web.Routing, Version=3.5.0.0, Culture=Neutral, PublicKeyToken=31bf3856ad364e35")]
+ public class RouteValueDictionary : IDictionary
+ {
+ private Dictionary _dictionary;
+
+ public RouteValueDictionary()
+ {
+ _dictionary = new Dictionary(StringComparer.OrdinalIgnoreCase);
+ }
+
+ public RouteValueDictionary(object values)
+ {
+ _dictionary = new Dictionary(StringComparer.OrdinalIgnoreCase);
+
+ AddValues(values);
+ }
+
+ public RouteValueDictionary(IDictionary dictionary)
+ {
+ _dictionary = new Dictionary(dictionary, StringComparer.OrdinalIgnoreCase);
+ }
+
+ public int Count
+ {
+ get
+ {
+ return _dictionary.Count;
+ }
+ }
+
+ public Dictionary.KeyCollection Keys
+ {
+ get
+ {
+ return _dictionary.Keys;
+ }
+ }
+
+ public Dictionary.ValueCollection Values
+ {
+ get
+ {
+ return _dictionary.Values;
+ }
+ }
+
+ public object this[string key]
+ {
+ get
+ {
+ object value;
+ TryGetValue(key, out value);
+ return value;
+ }
+ set
+ {
+ _dictionary[key] = value;
+ }
+ }
+
+ public void Add(string key, object value)
+ {
+ _dictionary.Add(key, value);
+ }
+
+ private void AddValues(object values)
+ {
+ if (values != null)
+ {
+ PropertyDescriptorCollection props = TypeDescriptor.GetProperties(values);
+ foreach (PropertyDescriptor prop in props)
+ {
+ object val = prop.GetValue(values);
+ Add(prop.Name, val);
+ }
+ }
+ }
+
+ public void Clear()
+ {
+ _dictionary.Clear();
+ }
+
+ public bool ContainsKey(string key)
+ {
+ return _dictionary.ContainsKey(key);
+ }
+
+ public bool ContainsValue(object value)
+ {
+ return _dictionary.ContainsValue(value);
+ }
+
+ public Dictionary.Enumerator GetEnumerator()
+ {
+ return _dictionary.GetEnumerator();
+ }
+
+ public bool Remove(string key)
+ {
+ return _dictionary.Remove(key);
+ }
+
+ public bool TryGetValue(string key, out object value)
+ {
+ return _dictionary.TryGetValue(key, out value);
+ }
+
+ #region IDictionary Members
+ ICollection IDictionary.Keys
+ {
+ get
+ {
+ return _dictionary.Keys;
+ }
+ }
+
+ ICollection