How to determine if an arbitrary URL matches a defined route

前端 未结 1 793
再見小時候
再見小時候 2020-12-05 14:47

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

I have a route like this:

routes.MapRoute(
    \"FindYourNewRental\",
    \"find-your-ne         


        
相关标签:
1条回答
  • 2020-12-05 15:36

    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");
    
    0 讨论(0)
提交回复
热议问题