2013-09-27 5 views
0

Я использую маршрутизацию ASP.NET 4.0 и считываю информацию маршрута из базы данных и добавляю маршруты, как показано ниже. В двух словах, мой пользовательский объект «RouteLookup» содержит информацию о маршруте, включая идентификатор другого RouteLookup, к которому он может перенаправляться или не может быть перенаправлен. Вот пример двух записей RouteLookup в БД:Почему RedirectToRoutePermanent добавляет «count = 0» к querystring?

RouteLookupID RouteName  RelativePath RequestHandler RouteHandler IsSecure RedirectedToRoute 
    13    PrivacyRoute about/privacy privacy.aspx NULL    0    0 
    14    PrivacyRoute1 privacy   privacy.aspx NULL    0    13  

RouteLookupID 14 является наследством маршрут, который должен быть постоянно перенаправлены на RouteLookupID 13. Проблема я бегу против, когда я прошу «http://mydomain.com/privacy» из браузер и смотреть результаты Fiddler, он фактически перенаправляет TWICE и добавляет «count = 0» в качестве параметра querystring! У меня нет ИДЕИ, откуда этот параметр исходит, поскольку у меня нет процесса, httphandler и т. Д., Который явно добавляет его.

Что, черт возьми, происходит здесь? Любые идеи очень ценятся, а остальная часть соответствующего кода ниже.

У меня есть класс BaseRoute, который наследуется от Route, поэтому я могу передать свой собственный объект RouteLookup вместе с ним для проверки в пользовательском RouteHandler, который я назвал BaseRouteHandler.

Public Class PageRouter 

Private Shared db As New QADBDataContext 

''''''' Is called from Global Application_Start 
Public Shared Sub MapRoutes(routeColl As RouteCollection) 

    Dim routeLookups As IEnumerable(Of RouteLookup) = From rt In db.RouteLookups Select rt 

    For Each rtLookUp As RouteLookup In routeLookups 
     Dim parameterizedURL As String = BuildParameterizedVirtualPath(rtLookUp) 

      ' Determine handler and route values 
      If rtLookUp.RouteHandler Is Nothing Then 
       RouteTable.Routes.Add(rtLookUp.RouteName, New BaseRoute(parameterizedURL, New BaseRouteHandler(), rtLookUp)) 
      Else 
       RouteTable.Routes.Add(rtLookUp.RouteName, New BaseRoute(parameterizedURL, Activator.CreateInstance(Type.GetType("QA." + rtLookUp.RouteHandler)), rtLookUp)) 
      End If    
    Next 
End Sub 

Protected Shared Function BuildParameterizedVirtualPath(rtLookUp As RouteLookup) As String 

    Dim parameterizedURL As String = rtLookUp.RelativePath 
    For Each param As RouteParameter In rtLookUp.RouteParameters 
     parameterizedURL &= "/{" + param.Name + "}" 
    Next 
    Return parameterizedURL 

End Function 

Public Shared Sub RedirectToRoutePermanent(rtData As RouteData) 

    Dim route As BaseRoute = DirectCast(rtData.Route, BaseRoute) 
    Dim rtLookup As RouteLookup = route.RouteLookup 
    Dim newRtLookupID As Integer = rtLookup.RedirectedToRoute 
    Dim newRtLookup As RouteLookup = (From rt In db.RouteLookups Where rt.RouteLookupID = newRtLookupID).SingleOrDefault 
    HttpContext.Current.Response.RedirectToRoutePermanent(newRtLookup.RouteName, rtData.Values.Values) 

End Sub 
End Class 

Пользовательские маршрут Класс:

Public Class BaseRoute 
Inherits Route 

Private _routeLookup As RouteLookup = Nothing 

Public Sub New(url As String, routeHandler As IRouteHandler, routeLookup As RouteLookup) 
    MyBase.New(url, routeHandler) 
    _routeLookup = routeLookup 

End Sub 

Public ReadOnly Property RouteLookup As RouteLookup 
    Get 
     Return _routeLookup 
    End Get 
End Property 
End Class 

Пользовательские RouteHandler:

Public Class BaseRouteHandler 
Implements IRouteHandler 

Protected _baseRoute As BaseRoute = Nothing 
Protected _rtLookup As RouteLookup = Nothing 

Protected Overridable Sub InitializeContext(ByVal requestContext As System.Web.Routing.RequestContext) 

    _baseRoute = DirectCast(requestContext.RouteData.Route, BaseRoute) 
    _rtLookup = _baseRoute.RouteLookup 

End Sub 


Public Function GetHttpHandler(ByVal requestContext As System.Web.Routing.RequestContext) _ 
         As System.Web.IHttpHandler Implements System.Web.Routing.IRouteHandler.GetHttpHandler 

    InitializeContext(requestContext) 
    EnforceURLStandard(requestContext) 
    PerformRedirectIfNeeded(requestContext) 
    Return GetPageHandler(requestContext) 

End Function 


Protected Overridable Sub PerformRedirectIfNeeded(ByVal requestContext As System.Web.Routing.RequestContext) 

    If _rtLookup.RedirectedToRoute > 0 Then 
     PageRouter.RedirectToRoutePermanent(requestContext.RouteData) 
    End If 

End Sub 


Protected Sub EnforceURLStandard(ByVal requestContext As System.Web.Routing.RequestContext) 

    ' Test for: 
    ' * Proper protocol 
    ' * www. exists 
    ' * must be all lowercase 

    Dim scheme As String = HttpContext.Current.Request.Url.GetComponents(UriComponents.Scheme, UriFormat.UriEscaped) 
    Dim rightSide As String = HttpContext.Current.Request.Url.GetComponents(UriComponents.HostAndPort Or UriComponents.PathAndQuery, UriFormat.UriEscaped) 
    Dim newURL As String = Nothing 

    If Not rightSide.ToLower().StartsWith("www.") AndAlso Not rightSide.ToLower().StartsWith("localhost") _ 
     AndAlso Not rightSide.ToLower().StartsWith("uat") AndAlso Not rightSide.ToLower().StartsWith("ux") Then 
     newURL = scheme & "://www." & rightSide 
    End If 

    If _rtLookup.IsSecure <> requestContext.HttpContext.Request.IsSecureConnection Then 
     Dim newScheme As String = If(_rtLookup.IsSecure, "https", "http") 
     newURL = newScheme & rightSide 
    End If 

    Dim pattern As String = "[A-Z]" 
    If Not String.IsNullOrWhiteSpace(newURL) Then 
     If Regex.IsMatch(newURL, pattern) Then 
      newURL = newURL.ToLower() 
     End If 
    Else 
     If Regex.IsMatch(HttpContext.Current.Request.Url.ToString(), pattern) Then 
      newURL = HttpContext.Current.Request.Url.ToString().ToLower() 
     End If 
    End If 

    If Not newURL Is Nothing Then 
     HttpContext.Current.Response.RedirectPermanent(newURL, True) 
    End If 

End Sub 

Protected Overridable Function GetPageHandler(ByVal requestContext As System.Web.Routing.RequestContext) As System.Web.IHttpHandler 

    Return TryCast(BuildManager.CreateInstanceFromVirtualPath("/" & _rtLookup.RequestHandler, GetType(Page)), Page) 

End Function 

End Class 

ответ

0

Ну, понял, что здесь происходит. RedirectToRoutePermanent не завершает запрос, такой как RedirectPermanent (url, true). Я переписал PageRouter.RedirectToRoutePermanent как таковой, который разрешил проблему:

Public Shared Sub RedirectToRoutePermanent(rtData As RouteData) 

    Dim route As BaseRoute = DirectCast(rtData.Route, BaseRoute) 
    Dim rtLookup As RouteLookup = route.RouteLookup 
    Dim newRtLookupID As Integer = rtLookup.RedirectedToRoute 
    Dim newRtLookup As RouteLookup = (From rt In db.RouteLookups Where rt.RouteLookupID = newRtLookupID).SingleOrDefault 

    Dim hostAndPort As String = HttpContext.Current.Request.Url.GetComponents(UriComponents.HostAndPort, UriFormat.UriEscaped) 
    Dim newURL As String = Nothing 

    Dim scheme As String = If(rtLookup.IsSecure, "https", "http") 
    newURL = scheme & "://" & hostAndPort 
    newURL &= "/" & newRtLookup.RelativePath 

    If rtData.Values.Count > 1 Then 
     For i As Integer = 1 To rtData.Values.Count - 1 
      newURL &= "/" & rtData.Values(i) 
     Next 
    End If 

    HttpContext.Current.Response.RedirectPermanent(newURL, True) 

End Sub 
Смежные вопросы