Я использую маршрутизацию 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