Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to determine if an arbitrary URL matches a defined route

How can I tell if a string matches a particular named route?

I have a route like this:

routes.MapRoute(
    "FindYourNewRental",
    "find-your-new-rental/{market}/{community}.html",
    new { controller = "FindYourNewRental", action = "Community" }
    );

string url = "http://www.website.com/find-your-new-rental/northerncalifornia/sacramento.html"

How can I programmatically tell if the 'url' string matches that route? Something like this:

// matches url with the named route "FindYourNewRental"
if (IsRouteMatch(url, "FindYourNewRental")) 
{
    // do something
}

public bool IsRouteMatch(string url, string routeName)
{
     // How do I code this function
}
like image 631
Scott Avatar asked Jan 20 '11 14:01

Scott


People also ask

Is a URL a route?

A route is a URL pattern that is mapped to a handler. The handler can be a physical file, such as an . aspx file in a Web Forms application. A handler can also be a class that processes the request.

What is App UseRouting ()?

UseRouting adds route matching to the middleware pipeline. This middleware looks at the set of endpoints defined in the app, and selects the best match based on the request. UseEndpoints adds endpoint execution to the middleware pipeline. It runs the delegate associated with the selected endpoint.

What would you use to add convention-based routes to an asp net core application?

In order to use convention-based routing, we must do two things in our Startup. cs class. The AddControllersWithViews() method is new in ASP.NET Core 3.0, and adds MVC controller and views to the service layer so that we might use Dependency Injection (DI) for them.

What is routing and how can you define routes in asp net core?

In ASP.NET Core MVC, this process is known as routing. Routing is the process of directing an HTTP request to a controller. Let us now understand how to route requests to different controllers. The ASP.NET Core middleware needs a way to determine if a given HTTP request should go to a controller for processing or not.


1 Answers

I solved this by adding a custom RouteInfo class which creates a new HttpContext with the supplied url and application path and uses that to obtain an instance of RouteData based on the new HttpContext object. I can then evaluate the Controller and Action values to see which route was matched. I have this wired up to an extension method on the Uri class. It feels a bit hackish and I was hoping there was a cleaner way to do this so I'll leave the question open in case someone else has a better solution.

ROUTEINFO CLASS:

public class RouteInfo
    {
        public RouteInfo(RouteData data)
        {
            RouteData = data;
        }

        public RouteInfo(Uri uri, string applicationPath)
        {
            RouteData = RouteTable.Routes.GetRouteData(new InternalHttpContext(uri, applicationPath));
        }

        public RouteData RouteData { get; private set; }

        private class InternalHttpContext : HttpContextBase
        {
            private readonly HttpRequestBase _request;

            public InternalHttpContext(Uri uri, string applicationPath) : base()
            {
                _request = new InternalRequestContext(uri, applicationPath);
            }

            public override HttpRequestBase Request { get { return _request; } }
        }

        private class InternalRequestContext : HttpRequestBase
        {
            private readonly string _appRelativePath;
            private readonly string _pathInfo;

            public InternalRequestContext(Uri uri, string applicationPath) : base()
            {
                _pathInfo = ""; //uri.Query; (this was causing problems, see comments - Stuart)

                if (String.IsNullOrEmpty(applicationPath) || !uri.AbsolutePath.StartsWith(applicationPath, StringComparison.OrdinalIgnoreCase))
                    _appRelativePath = uri.AbsolutePath;
                else
                    _appRelativePath = uri.AbsolutePath.Substring(applicationPath.Length);
            }

            public override string AppRelativeCurrentExecutionFilePath { get { return String.Concat("~", _appRelativePath); } }
            public override string PathInfo { get { return _pathInfo; } }
        }
    }

URI EXTENSION METHOD:

    /// <summary>
    /// Extension methods for the Uri class
    /// </summary>
    public static class UriExtensions
    {
        /// <summary>
        /// Indicates whether the supplied url matches the specified controller and action values based on the MVC routing table defined in global.asax.
        /// </summary>
        /// <param name="uri">A Uri object containing the url to evaluate</param>
        /// <param name="controllerName">The name of the controller class to match</param>
        /// <param name="actionName">The name of the action method to match</param>
        /// <returns>True if the supplied url is mapped to the supplied controller class and action method, false otherwise.</returns>
        public static bool IsRouteMatch(this Uri uri, string controllerName, string actionName)
        {
            RouteInfo routeInfo = new RouteInfo(uri, HttpContext.Current.Request.ApplicationPath);
            return (routeInfo.RouteData.Values["controller"].ToString() == controllerName && routeInfo.RouteData.Values["action"].ToString() == actionName);
        }
    }

USAGE:

Uri url = new Uri("http://www.website.com/find-your-new-rental/northerncalifornia/sacramento.html");

if (url.IsRouteMatch("FindYourNewRental", "Community"))
{
    // do something
}

OR

if (Request.Url.IsRouteMatch("FindYourNewRental", "Community"))
    {
        // do something
    }

ADDED BONUS: Because the RouteInfo class gives me back an instance of RouteData, I can access the route parameters as well. This led to the creation of another Uri extension method:

public static string GetRouteParameterValue(this Uri uri, string paramaterName)
        {
            RouteInfo routeInfo = new RouteInfo(uri, HttpContext.Current.Request.ApplicationPath);
            return routeInfo.RouteData.Values[paramaterName] != null ? routeInfo.RouteData.Values[paramaterName].ToString() : null;
        }

Which can now be used like so:

string someValue = url.GetRouteParameterValue("ParameterName");
like image 85
Scott Avatar answered Oct 17 '22 20:10

Scott