views:

41

answers:

2

I need to get RoutData by given URL string in ASP.NET MVC application.

I've found the way that I need to mock HttpContextBase based on my URL string and then pass it to RouteTable.Routes.GetRouteData() method in Route Parsing (Uri to Route) thread.

How to mock HttpContextBase to retrieve RouteData by URL string using RouteTable.Routes.GetRouteData()? Or is there another way to retrieve RouteData by URL?

A: 

I'm not sure I understand you question.

Either access the RouteData property on the Controller <controller/this>.RouteData MSDN - System.Web.MVC Controller.RouteData Property

or

Read ScottGu's Blog ASP.NET MVC Framework (Part2): URL Routing

Erik Philips
Yes, I can. I forgot mention that I need `RoteData` outside contoller's context. Blog about routing is not useful to me - I know how to setup routings.
SergeanT
This is interesting! You have a condition in which you need routedata prior to routing? If there is a simple explanation why this would be the case, would you share the reasoning?
Erik Philips
I need it to determine controller and action in HttpModule (that handles exceptions, preventing 302 Found status message) to route request handling to my controller specified in `customErrors` section like `~/Error/AccessDenied`. `Server.Transfer` doesn't work in case of MVC. So I need to determine what controller and action correspond to `~/Error/AccessDenied`.
SergeanT
A: 

I used Moq to determine what members of HttpContextBase are used in GetRouteData(). They are:

  • Request
    • AppRelativeCurrentExecutionFilePath
    • PathInfo

Request.AppRelativeCurrentExecutionFilePath should return path with ~, what I exactly need, so utility class may be like this one:

public static class RouteUtils
{
    public static RouteData GetRouteDataByUrl(string url)
    {
        return RouteTable.Routes.GetRouteData(new RewritedHttpContextBase(url));
    }

    private class RewritedHttpContextBase : HttpContextBase
    {
        private readonly HttpRequestBase mockHttpRequestBase;

        public RewritedHttpContextBase(string appRelativeUrl)
        {
            this.mockHttpRequestBase = new MockHttpRequestBase(appRelativeUrl);
        }


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

        private class MockHttpRequestBase : HttpRequestBase
        {
            private readonly string appRelativeUrl;

            public MockHttpRequestBase(string appRelativeUrl)
            {
                this.appRelativeUrl = appRelativeUrl;
            }

            public override string AppRelativeCurrentExecutionFilePath
            {
                get { return appRelativeUrl; }
            }

            public override string PathInfo
            {
                get { return ""; }
            }
        }
    }
}

If you pass ~/Error/NotFound, for example, RouteUtils.GetRouteByUrl("~/Error/NotFound") returns something like

RouteData.Values
{
    controller = "Error",
    action = "NotFound"
}

Maybe this will be helpful for anybody.

SergeanT