Exemplo n.º 1
0
        static KeyValuePair <string, IHttpRoute>[] CopyRouteEntries(HttpRouteCollection routes)
        {
            Contract.Requires(routes != null);
            Contract.Ensures(Contract.Result <KeyValuePair <string, IHttpRoute>[]>() != null);

            var items = new KeyValuePair <string, IHttpRoute> [routes.Count];

            try
            {
                routes.CopyTo(items, 0);
            }
            catch (NotSupportedException) when(routes.GetType().FullName == "System.Web.Http.WebHost.Routing.HostedHttpRouteCollection")
            {
                var keys = GetRouteKeys(routes);

                for (var i = 0; i < keys.Count; i++)
                {
                    var key   = keys[i];
                    var route = routes[key];

                    items[i] = new KeyValuePair <string, IHttpRoute>(key, route);
                }
            }

            return(items);
        }
Exemplo n.º 2
0
        static ICollection <string> GetDictionaryKeys(HttpRouteCollection routes)
        {
            // HACK: System.Web.Routing.RouteCollection doesn't expose the names associated with registered routes. The
            // HostedHttpRouteCollection could have provided an adapter to support it, but didn't. Instead, it always throws
            // NotSupportedException for the HttpRouteCollection.CopyTo method. This only happens when hosted on IIS. The
            // only way to get the keys is use reflection to poke at the underlying dictionary.
            var routeCollection = routes.GetType().GetField("_routeCollection", Instance | NonPublic).GetValue(routes);
            var dictionary      = routeCollection.GetType().GetField("_namedMap", Instance | NonPublic).GetValue(routeCollection);
            var keys            = (ICollection <string>)dictionary.GetType().GetRuntimeProperty("Keys").GetValue(dictionary, null);

            return(keys);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Returns the route collection as a read-only dictionary mapping configured names to routes.
        /// </summary>
        /// <param name="routes">The <see cref="HttpRouteCollection">route collection</see> to convert.</param>
        /// <returns>A new <see cref="IReadOnlyDictionary{TKey, TValue}">read-only dictonary</see> of
        /// <see cref="IHttpRoute">routes</see> mapped to their name.</returns>
        public static IReadOnlyDictionary <string, IHttpRoute> ToDictionary(this HttpRouteCollection routes)
        {
            Arg.NotNull(routes, nameof(routes));
            Contract.Ensures(Contract.Result <IReadOnlyDictionary <string, IHttpRoute> >() != null);

            const string HostedHttpRouteCollection = "System.Web.Http.WebHost.Routing.HostedHttpRouteCollection";

            try
            {
                return(routes.CopyToDictionary());
            }
            catch (NotSupportedException) when(routes.GetType().FullName == HostedHttpRouteCollection)
            {
                return(routes.BuildDictionaryFromKeys());
            }
        }
Exemplo n.º 4
0
        /// <summary>
        /// Returns the route collection as a read-only dictionary mapping configured names to routes.
        /// </summary>
        /// <param name="routes">The <see cref="HttpRouteCollection">route collection</see> to convert.</param>
        /// <returns>A new <see cref="IReadOnlyDictionary{TKey, TValue}">read-only dictonary</see> of
        /// <see cref="IHttpRoute">routes</see> mapped to their name.</returns>
        public static IReadOnlyDictionary <string, IHttpRoute> ToDictionary(this HttpRouteCollection routes)
        {
            if (routes == null)
            {
                throw new ArgumentNullException(nameof(routes));
            }

            const string HostedHttpRouteCollection = "System.Web.Http.WebHost.Routing.HostedHttpRouteCollection";

            try
            {
                return(routes.CopyToDictionary());
            }
            catch (NotSupportedException) when(routes.GetType().FullName == HostedHttpRouteCollection)
            {
                return(routes.BuildDictionaryFromKeys());
            }
        }