Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
671 views
in Technique[技术] by (71.8m points)

asp.net mvc - How to get RouteData by URL?

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

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

1 Reply

0 votes
by (71.8m points)

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...