Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
663 views
Welcome To Ask or Share your Answers For Others

1 Answer

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 ""; }
            }
        }
    }
}

Then, you can use it like this (for example on ~/Error/NotFound):

var rd = RouteUtils.GetRouteDataByUrl("~/Error/NotFound")

Which should return an object that looks like this:

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...