public void WriteBlocksWhileReadIsInEffect()
        {
            _routes.MapRoute("foo", "{controller}");

            var publisher = _container.Resolve <IRoutePublisher>();

            var readLock = _routes.GetReadLock();

            string where = "init";
            var action = new Action(() => {
                where = "before";
                publisher.Publish(new[] { Desc("barname", "bar"), Desc("quuxname", "quux") });
                where = "after";
            });

            Assert.That(where, Is.EqualTo("init"));
            var asyncResult = action.BeginInvoke(null, null);

            Thread.Sleep(75);
            Assert.That(where, Is.EqualTo("before"));
            readLock.Dispose();
            Thread.Sleep(75);
            Assert.That(where, Is.EqualTo("after"));
            action.EndInvoke(asyncResult);
        }
        // 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);
        }
Beispiel #3
0
        /// <summary>
        /// Writes to the log a list of the provided routes as Info statements
        /// </summary>
        /// <param name="filters">RouteCollection in most cases from RouteTable.Routes</param>
        protected void LogRoutes(RouteCollection routes)
        {
            String logMethodName = ".LogCurrentRoutes(RouteCollection routes) - ";

            _log.Debug(logMethodName + "Begin Method");
            _log.Info(logMethodName + "====== Currenlty Registered Routes ======");

            if (routes != null)
            {
                using (routes.GetReadLock())
                {
                    foreach (RouteBase routeBase in routes)
                    {
                        Route route = routeBase as Route;
                        if (route != null)
                        {
                            _log.Info(logMethodName
                                      + "Handler : " + route.RouteHandler.GetType().FullName.ToString()
                                      + " | Route - Url Pattern : " + route.Url);
                        }
                    }
                }
            }

            _log.Debug(logMethodName + "End Method");
        }
        // 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;
        }
        // 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;

            // Ensure that we continue using the same settings as the previous route collection
            // if we are using areas and the route collection is exchanged
            RouteCollection filteredRoutes = new RouteCollection()
            {
                AppendTrailingSlash = routes.AppendTrailingSlash,
                LowercaseUrls       = routes.LowercaseUrls,
                RouteExistingFiles  = routes.RouteExistingFiles
            };

            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);
        }
        // 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;

            // Ensure that we continue using the same settings as the previous route collection
            // if we are using areas and the route collection is exchanged
            RouteCollection filteredRoutes = new RouteCollection()
            {
                AppendTrailingSlash = routes.AppendTrailingSlash,
                LowercaseUrls = routes.LowercaseUrls,
                RouteExistingFiles = routes.RouteExistingFiles
            };

            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 void RewriteRoutesForTesting(RouteCollection routes)
        {
            using (routes.GetReadLock())
            {
                bool foundDebugRoute = false;
                foreach (RouteBase routeBase in routes)
                {
                    Route route = routeBase as Route;
                    if (route != null)
                    {
                        route.RouteHandler = new DebugRouteHandler();
                    }

                    if (route == DebugRoute.Singleton)
                        foundDebugRoute = true;

                }
                if (!foundDebugRoute)
                {
                    routes.Add(DebugRoute.Singleton);
                }
            }

            
        }
Beispiel #8
0
        public static void DebugRoutes()
        {
            RouteCollection routes = RouteTable.Routes;

            using (routes.GetReadLock())
            {
                bool flag = false;
                foreach (RouteBase base2 in routes)
                {
                    Route route = base2 as Route;
                    if (route != null)
                    {
                        route.RouteHandler = new DebugRouteHandler();
                    }
                    if (route == DebugRoute.Singleton)
                    {
                        flag = true;
                    }
                }
                if (!flag)
                {
                    routes.Add(DebugRoute.Singleton);
                }
            }
        }
Beispiel #9
0
        /// <summary>
        /// Determines whether the current request is reserved based on the route table and
        /// whether the specified URL is reserved or is inside a reserved path.
        /// </summary>
        /// <param name="url"></param>
        /// <param name="httpContext"></param>
        /// <param name="routes">The route collection to lookup the request in</param>
        /// <returns></returns>
        internal bool IsReservedPathOrUrl(string url, HttpContextBase httpContext, RouteCollection routes)
        {
            if (httpContext == null)
            {
                throw new ArgumentNullException(nameof(httpContext));
            }
            if (routes == null)
            {
                throw new ArgumentNullException(nameof(routes));
            }

            //This is some rudimentary code to check if the route table has changed at runtime, we're basically just keeping a count
            //of the routes. This isn't fail safe but there's no way to monitor changes to the route table. Else we need to create a hash
            //of all routes and then recompare but that will be annoying to do on each request and then we might as well just do the whole MVC
            //route on each request like we were doing before instead of caching the result of GetRouteData.
            var changed = false;

            using (routes.GetReadLock())
            {
                if (!_routeCount.HasValue || _routeCount.Value != routes.Count)
                {
                    //the counts are not set or have changed, need to reset
                    changed = true;
                }
            }
            if (changed)
            {
                using (routes.GetWriteLock())
                {
                    _routeCount = routes.Count;

                    //try clearing each entry
                    foreach (var r in RouteChecks.Keys.ToList())
                    {
                        RouteChecks.TryRemove(r, out _);
                    }
                }
            }

            var absPath = httpContext?.Request?.Url.AbsolutePath;

            if (absPath.IsNullOrWhiteSpace())
            {
                return(false);
            }

            //check if the current request matches a route, if so then it is reserved.
            var hasRoute = RouteChecks.GetOrAdd(absPath, x => routes.GetRouteData(httpContext) != null);

            if (hasRoute)
            {
                return(true);
            }

            //continue with the standard ignore routine
            return(IsReservedPathOrUrl(url));
        }
Beispiel #10
0
 // RouteCollection.GetVirtualPath does extra processing we don't want here
 private static VirtualPathData GetVirtualPathOnAllRoutes(RouteCollection routes, RequestContext requestContext, RouteValueDictionary values)
 {
     using (routes.GetReadLock()) {
         foreach (RouteBase route in routes) {
             VirtualPathData pathData = route.GetVirtualPath(requestContext, values);
             if (pathData != null) {
                 return pathData;
             }
         }
     }
     return null;
 }
Beispiel #11
0
        /// <summary>
        ///   <para>Assign route handler to all routes passed</para>
        /// </summary>
        /// <param name = "routes">Routes</param>
        public static void Assign(RouteCollection routes)
        {
            using (routes.GetReadLock())
            {
                var routeHandler
                    = new RouteHandler <THttpHandler>(
                          ControllerBuilder.Current.GetControllerFactory());

                foreach (var route in routes
                         .OfType <Route>()
                         .Where(r => (r.RouteHandler is MvcRouteHandler)))
                {
                    route.RouteHandler = routeHandler;
                }
            }
        }
        internal static bool DetermineUsingAreas(RouteCollection routes)
        {
            using (routes.GetReadLock())
            {
                foreach (RouteBase route in routes)
                {
                    string a = AreaHelpers.GetAreaName(route) ?? string.Empty;
                    if (a.Length > 0)
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
Beispiel #13
0
        /// <summary>
        /// Performs an action with a read lock on the route collection.
        /// </summary>
        /// <typeparam name="T">The result type.</typeparam>
        /// <param name="routes">The route collection.</param>
        /// <param name="action">The action to run.</param>
        /// <returns>The action result.</returns>
        internal static T UseWithReadLock <T>(this RouteCollection routes, Func <RouteCollection, T> action)
        {
            ADXTrace.Instance.TraceVerbose(TraceCategory.Application, "RouteCollection lock: Read: Requested");

            T result;

            using (routes.GetReadLock())
            {
                ADXTrace.Instance.TraceVerbose(TraceCategory.Application, "RouteCollection lock: Read: Acquired");

                result = action(routes);
            }

            ADXTrace.Instance.TraceVerbose(TraceCategory.Application, "RouteCollection lock: Write: Released");

            return(result);
        }
Beispiel #14
0
 // Methods
 public static void RewriteRoutesForTesting(RouteCollection routes)
 {
     using (routes.GetReadLock())
     {
         bool flag = false;
         foreach (RouteBase base2 in routes)
         {
             Route route = base2 as Route;
             if (route != null)
                 route.RouteHandler = new DebugRouteHandler();
             if (route == DebugRoute.Singleton)
                 flag = true;
         }
         if (!flag)
             routes.Add(DebugRoute.Singleton);
     }
 }
        private static RouteCollection FilterRouteCollectionByArea(RouteCollection routes, string areaName) {
            if (areaName == null) {
                areaName = String.Empty;
            }

            RouteCollection filteredRoutes = new RouteCollection();

            using (routes.GetReadLock()) {
                foreach (RouteBase route in routes) {
                    string thisAreaName = AreaHelpers.GetAreaName(route) ?? String.Empty;
                    if (String.Equals(thisAreaName, areaName, StringComparison.OrdinalIgnoreCase)) {
                        filteredRoutes.Add(route);
                    }
                }
            }

            return filteredRoutes;
        }
Beispiel #16
0
        public static void RewriteRoutesForTesting(RouteCollection routes)
        {
            using (routes.GetReadLock()) {
                bool foundDebugRoute = false;
                foreach (RouteBase routeBase in routes)
                {
                    Route route = routeBase as Route;
                    if (route != null)
                    {
                        route.RouteHandler = new DebugRouteHandler();
                    }

                    if (route == DebugRoute.Singleton)
                    {
                        foundDebugRoute = true;
                    }
                }
                if (!foundDebugRoute)
                {
                    routes.Add(DebugRoute.Singleton);
                }
            }
        }
Beispiel #17
0
 /// <summary>
 ///     重写路由表(作为测试)
 /// </summary>
 /// <param name="routes"></param>
 public static void RewriteRoutesForTesting(RouteCollection routes)
 {
     using (routes.GetReadLock())
     {
         bool flag = false;
         foreach (RouteBase routeBase in routes)
         {
             var route = routeBase as Route;
             if (route != null)
             {
                 route.RouteHandler = new DebugRouteHandler();
             }
             if (route == DebugRoute.Singleton)
             {
                 flag = true;
             }
         }
         if (flag)
         {
             return;
         }
         (routes).Add(DebugRoute.Singleton);
     }
 }
Beispiel #18
0
        // 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 RouteCollection FilterRouteCollectionByArea(RouteCollection routes, string areaName, out bool usingAreas)
        {
            // Copied over from https://github.com/aspnet/AspNetWebStack/blob/master/src/System.Web.Mvc/RouteCollectionExtensions.cs#L18

            if (areaName == null)
            {
                areaName = String.Empty;
            }

            usingAreas = false;

            // Ensure that we continue using the same settings as the previous route collection
            // if we are using areas and the route collection is exchanged
            RouteCollection filteredRoutes = new RouteCollection
            {
                AppendTrailingSlash = routes.AppendTrailingSlash,
                LowercaseUrls       = routes.LowercaseUrls,
                RouteExistingFiles  = routes.RouteExistingFiles
            };

            using (routes.GetReadLock())
            {
                foreach (RouteBase route in routes)
                {
                    string thisAreaName = route.GetAreaName() ?? 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 ActionResult SaveSettings(List <ParamNameValue> ParamNameValues)
        {
            List <ParamNameValue> WrongParams = new List <ParamNameValue>();
            string GeneralSecretAdminUrlOld   = AppParams.GeneralSecretAdminUrl.Value;
            string AppApiSecretURL            = AppParams.AppApiSecretURL.Value;

            foreach (ParamNameValue Param in ParamNameValues)
            {
                if (Param.Name == null || Param.Name.Length == 0)
                {
                    continue;
                }

                Parameter Parameter = Parameters.GetBy(Param.Name);
                Parameter.MemberID = Profile.Member.MemberID;

                string oldValue = Parameter.Value;
                Param.Value = Param.Value == null ? "" : Param.Value;

                if (Parameter.Type == ParameterType.Bool)
                {
                    if (Param.Value.ToLower() == "true")
                    {
                        Param.Value = Parameter.Value = "true";
                    }
                    else
                    {
                        Param.Value = Parameter.Value = "false";
                    }
                }
                else if (Parameter.Type == ParameterType.SmallInteger || Parameter.Type == ParameterType.RadioInteger)
                {
                    long value  = -1;
                    bool result = long.TryParse(Param.Value, out value);
                    Parameter.Value = result ? Param.Value : Parameter.Value;

                    if (!result)
                    {
                        WrongParams.Add(Param);
                    }
                }
                else
                {
                    Parameter.Value = Param.Value;
                }

                if (oldValue != Param.Value)
                {
                    Parameter.Save();
                }

                if (AppParams.GeneralAuditEnabled.Value == "true" && Param.Value != oldValue)
                {
                    AuditEvent.AppEventSuccess(Profile.Member.Email, String.Format("Changed: {0} -> from \"{1}\" to \"{2}\"", Parameter.Name, oldValue, Parameter.Value));
                }
            }

            AppParams.RefreshAppParameters();
            List <ParamNameValue> ParamValues = new List <ParamNameValue>();
            List <Parameter>      Params      = Parameters.Get();

            ////////////////////////////////////////////
            // Change admin route
            ////////////////////////////////////////////
            bool   AdminRouteChaned  = false;
            string RelativeAdminPath = "{controller}/{action}/{id}";

            if (AppParams.GeneralSecretAdminUrl != null && AppParams.GeneralSecretAdminUrl.Value.Length > 0 && GeneralSecretAdminUrlOld != AppParams.GeneralSecretAdminUrl.Value)
            {
                RouteCollection routes = RouteTable.Routes;
                using (routes.GetWriteLock())
                {
                    RelativeAdminPath = Path.Combine(AppSession.Parameters.GeneralSecretAdminUrl.Value.Replace("/", "\\"), RelativeAdminPath.Replace("/", "\\")).Replace("\\", "/");

                    if (RelativeAdminPath[0] == '/')
                    {
                        RelativeAdminPath = RelativeAdminPath.Remove(0, 1);
                    }

                    Route route = (Route)routes["Admin-Secret-Path"];
                    route.Url = RelativeAdminPath;
                }

                // If admin route changed redirect admin to correct url
                AdminRouteChaned = true;
            }
            else if ((AppParams.GeneralSecretAdminUrl == null || AppParams.GeneralSecretAdminUrl.Value.Length == 0) && GeneralSecretAdminUrlOld != AppParams.GeneralSecretAdminUrl.Value)
            {
                RouteCollection routes = RouteTable.Routes;
                using (routes.GetReadLock())
                {
                    Route route = (Route)routes["Admin-Secret-Path"];
                    route.Url = "Admin/" + RelativeAdminPath;
                }

                AdminRouteChaned = true;
            }

            ////////////////////////////////////////////
            // Change API route
            ////////////////////////////////////////////
            bool   APIRouteChaned  = false;
            string RelativeAPIPath = "{action}/{id}";

            if (AppParams.AppApiSecretURL != null && AppParams.GeneralSecretAdminUrl.Value.Length > 0 && AppApiSecretURL != AppParams.AppApiSecretURL.Value)
            {
                RouteCollection routes = RouteTable.Routes;
                using (routes.GetWriteLock())
                {
                    RelativeAPIPath = Path.Combine(AppSession.Parameters.AppApiSecretURL.Value.Replace("/", "\\"), RelativeAPIPath.Replace("/", "\\")).Replace("\\", "/");

                    if (RelativeAdminPath[0] == '/')
                    {
                        RelativeAdminPath = RelativeAPIPath.Remove(0, 1);
                    }

                    Route route = (Route)routes["API-Secret-Path"];
                    route.Url = RelativeAPIPath;
                }

                // If API route changed redirect admin to correct url
                APIRouteChaned = true;
            }
            else if ((AppParams.AppApiSecretURL == null || AppParams.AppApiSecretURL.Value.Length == 0) && AppApiSecretURL != AppParams.AppApiSecretURL.Value)
            {
                RouteCollection routes = RouteTable.Routes;
                using (routes.GetReadLock())
                {
                    Route route = (Route)routes["API-Secret-Path"];
                    route.Url = "Admin/API/" + RelativeAPIPath;
                }

                APIRouteChaned = true;
            }


            foreach (Parameter Param in Params)
            {
                ParamValues.Add(new ParamNameValue {
                    Name = Param.Name, Value = Param.Value, Type = Param.Type.ToString()
                });
            }


            string             Message         = "";
            string             AdminUrlChanged = "";
            string             APIUrlChanged   = "";
            RequestResultModel _model          = new RequestResultModel();

            if (AdminRouteChaned)
            {
                AdminUrlChanged = String.Format("<br/><strong>Admin URL has been changed. Click <a href=\"{0}\">here</a> to redirect to actual admin URL.</strong>", Url.Action("", "Settings"));
            }

            if (APIRouteChaned)
            {
                string Path = (AppParams.AppApiSecretURL.Value.Length > 0 ? AppParams.AppApiSecretURL.Value : "Admin/API");
                APIUrlChanged = String.Format("<br/>API URL has been changed. Please update all API clients. Here is base url now: <strong>{0}</strong>", Path);
            }


            if (WrongParams.Count == 0)
            {
                _model.Title    = GetLabel("Account.Controller.Congrat");
                _model.InfoType = RequestResultInfoType.Success;
                _model.Message  = "Application settngs have been saved." + AdminUrlChanged + APIUrlChanged;
                Message         = this.RenderPartialView(@"_RequestResultDialogInLine", _model);
            }
            else
            {
                _model.Title    = GetLabel("Account.Controller.Warning");
                _model.InfoType = RequestResultInfoType.ErrorOrDanger;
                _model.Message  = "Some parametrs have not been saved. Please check." + AdminUrlChanged + APIUrlChanged;
                Message         = this.RenderPartialView(@"_RequestResultDialogInLine", _model);
            }



            return(Json(new
            {
                Message = Message,
                Settings = ParamValues,
            }, JsonRequestBehavior.AllowGet));
        }
Beispiel #20
0
        public void ProcessRequest(HttpContextBase context, RouteCollection routeTable)
        {
            string htmlFormat    = @"<html>
<head>
    <title>Route Tester</title>
    <style>
        body, td, th {{font-family: verdana; font-size: small;}}
        .message {{font-size: .9em;}}
        caption {{font-weight: bold;}}
        tr.header {{background-color: #ffc;}}
        label {{font-weight: bold; font-size: 1.1em;}}
        .false {{color: #c00;}}
        .true {{color: #0c0;}}
    </style>
</head>
<body>
<h1>Route Tester</h1>
<div id=""main"">
    <p class=""message"">
        Type in a url in the address bar to see which defined routes match it. 
        A {{*catchall}} route is added to the list of routes automatically in 
        case none of your routes match.
    </p>
    <p><label>Route</label>: {1}</p>
    <table border=""1"" cellpadding=""3"" cellspacing=""0"">
        <caption>Route Data</caption>
        <tr class=""header""><th>Key</th><th>Value</th></tr>
        {0}
    </table>
    <hr />
    <table border=""1"" cellpadding=""3"" cellspacing=""0"">
        <caption>All Routes</caption>
        <tr class=""header"">
            <th>Matches Current Request</th>
            <th>Url</th>
            <th>Defaults</th>
            <th>Constraints</th>
            <th>DataTokens</th>
        </tr>
        {2}
    </table>
</div>
</body>
</html>";
            string routeDataRows = string.Empty;

            RouteData            routeData        = RequestContext.RouteData;
            RouteValueDictionary routeValues      = routeData.Values;
            RouteBase            matchedRouteBase = routeData.Route;

            string routes = string.Empty;

            using (routeTable.GetReadLock())
            {
                foreach (var routeBase in routeTable)
                {
                    bool   matchesCurrentRequest = (routeBase.GetRouteData(RequestContext.HttpContext) != null);
                    string matchText             = string.Format(@"<span class=""{0}"">{0}</span>", matchesCurrentRequest);
                    string url         = "n/a";
                    string defaults    = "n/a";
                    string constraints = "n/a";
                    string dataTokens  = "n/a";

                    var route = routeBase as Route;
                    if (route != null)
                    {
                        url         = route.Url;
                        defaults    = FormatRouteValueDictionary(route.Defaults);
                        constraints = FormatRouteValueDictionary(route.Constraints);
                        dataTokens  = FormatRouteValueDictionary(route.DataTokens);
                    }

                    routes += string.Format(@"<tr><td>{0}</td><td>{1}</td><td>{2}</td><td>{3}</td><td>{4}</td></tr>"
                                            , matchText
                                            , url
                                            , defaults
                                            , constraints
                                            , dataTokens);
                }
            }

            string matchedRouteUrl = "n/a";

            if (!(matchedRouteBase is DebugRoute))
            {
                foreach (var key in routeValues.Keys)
                {
                    routeDataRows += string.Format("\t<tr><td>{0}</td><td>{1}&nbsp;</td></tr>", key, routeValues[key]);
                }

                var matchedRoute = matchedRouteBase as Route;

                if (matchedRoute != null)
                {
                    matchedRouteUrl = matchedRoute.Url;
                }
            }
            else
            {
                matchedRouteUrl = "<strong class=\"false\">NO MATCH!</strong>";
            }

            context.Response.Output.Write(string.Format(htmlFormat
                                                        , routeDataRows
                                                        , matchedRouteUrl
                                                        , routes));
        }