ASP.NET MVC:Uri到可用的路由数据

时间:2009-12-10 17:26:52

标签: asp.net-mvc routing asp.net-mvc-routing

我的问题非常简单。我有一个Uri,我想知道它映射到哪条路线,所以我可以对路线的各个部分进行一些检查:控制器,动作等。

如何从Uri前往RouteData或Route?

3 个答案:

答案 0 :(得分:4)

根据@ tvanfosson的指示,我想出了一个能满足我需要的课程。请注意,GetRouteData实际上会查看AppRelativeCurrentExecutionFilePath类的PathInfoRequestContextBase属性,而不是Url属性。

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

    //********************
    //Miscellaneous properties here to deal with routing conditionals... (e.g. "CanRedirectFromSignIn")
    //********************

    private class InternalHttpContext : HttpContextBase
    {
        private 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 string _appRelativePath;
        private string _pathInfo;

        public InternalRequestContext(Uri uri, string applicationPath) : base()
        {
            _pathInfo = uri.Query;

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

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

答案 1 :(得分:2)

您可以尝试扩展HttpRequestBase并覆盖Uri属性,以便您可以根据请求将Uri分配给属性。然后重写HttpContextBase以允许您在上下文中设置Request属性。然后,您可以使用RouteCollection类上的GetRouteData()方法来获取合适的RouteValueDictionary。请注意,RouteCollection在RouteTable类上可用作静态属性。

var myRequest = new MyRequest( myUri );
var myContext = new MyContext( myRequest );
var routeData = RouteTable.Routes.GetRouteData( myContext );

<强>更新

对于您的用例(注释),您可以简单地匹配控制器/操作:

if (myUri.ToString().ToLower().Contains( "/controller/action" ))
{
     return RedirectToAction( action, controller, new { ...route data } );
}
else
{
     return Redirect( "http://www.example.com/default" );
}

答案 2 :(得分:1)

取决于你是否可以改变当前请求的路径(在我的情况下我是)这里是一个非常简单的解决方案,不涉及嘲笑任何事情:

HttpContext httpContext = HttpContext.Current;
httpContext.RewritePath(URL);
RouteData route = RouteTable.Routes.GetRouteData(new HttpContextWrapper(httpContext));