2009-12-10 4 views
4

Моя проблема довольно проста. У меня есть Ури, и я хочу выяснить, к какому маршруту он относится, поэтому я могу сделать некоторые проверки на разных участках маршрута: контроллер, действие и т. Д.ASP.NET MVC: Uri для использования данных маршрута

Как перейти от Uri к RouteData или Маршрут?

ответ

4

на основе направления @ tvanfosson, я придумал класс, который делает то, что мне нужно. Обратите внимание, что GetRouteData фактически смотрит на AppRelativeCurrentExecutionFilePath и PathInfo на RequestContextBase класс, а не 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; } } 
    } 
} 
+0

Примечание. Это, вероятно, должно содержать дополнительную проверку, чтобы убедиться, что Uri является абсолютным ... в противном случае это дерьмо. – mkedobbs

2

Возможно, вы попробуете расширить HttpRequestBase и переопределить свойство Uri, чтобы вы могли присвоить свой Uri собственности по запросу. Затем переопределите HttpContextBase, чтобы вы могли установить свойство Request в контексте. Затем вы можете использовать метод GetRouteData() в классе RouteCollection, чтобы получить подходящий RouteValueDictionary. Обратите внимание, что RouteCollection доступен как статическое свойство класса RouteTable.

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

Update:

Для вашего случая использования (комментарии), вы могли бы просто соответствовать на контроллер/действие:

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

Wow , Похоже, что действительно должен быть менее запутанный способ, чем это ... – mkedobbs

+0

Мне никогда не нужно было это делать, поскольку инфраструктура обрабатывает его. Что такое ваш прецедент? – tvanfosson

+0

Все, с чем мне нужно иметь дело - это Uri, и мне нужно перенаправить, если Uri соответствует определенным критериям (сопоставьте конкретному контроллеру с определенным действием), иначе перенаправляйтесь на URI по умолчанию. – mkedobbs

1

В зависимости от того, если вы все в порядке с изменением пути текущего запроса (В моем случае я) здесь очень простое решение, которое не связано с насмешливым что-нибудь:

HttpContext httpContext = HttpContext.Current; 
httpContext.RewritePath(URL); 
RouteData route = RouteTable.Routes.GetRouteData(new HttpContextWrapper(httpContext)); 
Смежные вопросы