The one big limitation of the URL Mapping functionality built in to ASP.NET 2.0 is that it doesn't support regular expressions. I ported my v1.1 URL Mapping implementation over to v2.0 and added support for regular expressions. It really wasn't too difficult; I only had to modify two lines of code to port it over to ASP.NET 2.0. Then I had to modify 4 lines of code to add RegEx support. My implementation works just like the ASP.NET 2.0 URL Mapping functionality with the addition of RegEx.chemas-microsoft-com
ffice
ffice" />>>
My code allows to create Url Mappings similar to the following:
~/Chris.aspx to ~/Default.aspx?p=chris
~/Show154.aspx to ~/Default.aspx?p=154>>
Some Performance tips for using this code:>>
1. Use as few Url Mapping definitions as possible since it parses them from the first to the last and stops when it finds a match. If a page requested doesn't match any of the definitions it will go through all of them before moving on to complete the page request. >>
2. Put the most frequently used Url Mappings first in the list so that they the ones that are parsed first.>>
3. The first Url Mapping in placed in my code (<add url="~/(.*)default\.aspx" mappedUrl="~/$1default.aspx" />) is a little trick that allows all requests for the Default.aspx page in the root or any sub-folder of the application to be completed with out having to parse through the entire list of Url Mappings.>>
Regular expression support just seems logical in the v2.0 URL Mapping functionality, but I don't know why Microsoft didn't add it. I guess they wanted me to have something to do. :)>>
Enjoy!>>
Code for this implementation listed below:>>
/App_Code/RegExUrlMappingBaseModule.vb>>
Imports Microsoft.VisualBasic>>
Imports System.Web>>
Namespace RegExUrlMapping_HTTPModule>>
Public Class RegExUrlMappingBaseModule>>
Implements System.Web.IHttpModule>>
Sub Init(ByVal app As HttpApplication) Implements IHttpModule.Init>>
AddHandler app.AuthorizeRequest, AddressOf Me.BaseModuleRewriter_AuthorizeRequest>>
End Sub>>
Sub Dispose() Implements System.Web.IHttpModule.Dispose>>
End Sub>>
Sub BaseModuleRewriter_AuthorizeRequest(ByVal sender As Object, ByVal e As EventArgs)>>
Dim app As HttpApplication = CType(sender, HttpApplication)>>
Rewrite(app.Request.Path, app)>>
End Sub>>
Overridable Sub Rewrite(ByVal requestedPath As String, ByVal app As HttpApplication)>>
End Sub>>
End Class>>
End Namespace>>
/App_Code/RegExUrlMappingConfigHandler.vb>>
Imports Microsoft.VisualBasic>>
Imports System.Configuration>>
Imports System.Xml>>
Namespace RegExUrlMapping_HTTPModule>>
Public Class RegExUrlMappingConfigHandler>>
Implements IConfigurationSectionHandler>>
Dim _Section As XmlNode>>
Public Function Create(ByVal parent As Object, ByVal configContext As Object, ByVal section As System.Xml.XmlNode) As Object Implements System.Configuration.IConfigurationSectionHandler.Create>>
_Section = section>>
Return Me>>
End Function>>
''' Get whether url mapping is enabled in the app.config>>
Friend Function Enabled() As Boolean>>
If _Section.Attributes("enabled").Value.ToLower = "true" Then>>
Return True>>
Else>>
Return False>>
End If>>
End Function>>
''' Get the matching "mapped Url" from the web.config file if there is one.>>
Friend Function MappedUrl(ByVal url As String) As String>>
Dim x As XmlNode>>
Dim oReg As Regex>>
For Each x In _Section.ChildNodes>>
oReg = New Regex(x.Attributes("url").Value.ToLower)>>
If oReg.Match(url).Success Then>>
Return oReg.Replace(url, x.Attributes("mappedUrl").Value.ToLower)>>
End If>>
Next>>
Return "">>
End Function>>
End Class>>
End Namespace>>
/App_Code/RegExUrlMappingModule.vb>>
Imports Microsoft.VisualBasic>>
Imports System.Web>>
Imports System.Configuration>>
Namespace RegExUrlMapping_HTTPModule>>
Public Class RegExUrlMappingModule>>
Inherits RegExUrlMappingBaseModule>>
Overrides Sub Rewrite(ByVal requestedPath As String, ByVal app As HttpApplication)>>
''Implement functionality here that mimics the 'URL Mapping' features of ASP.NET 2.0>>
Dim config As RegExUrlMappingConfigHandler = CType(ConfigurationManager.GetSection("system.web/RegExUrlMapping"), RegExUrlMappingConfigHandler)>>
Dim pathOld As String, pathNew As String = "">>
If config.Enabled Then>>
pathOld = app.Request.RawUrl>>
''Get the request page without the querystring parameters>>
Dim requestedPage As String = app.Request.RawUrl.ToLower>>
If requestedPage.IndexOf("?") > -1 Then>>
requestedPage = requestedPage.Substring(0, requestedPage.IndexOf("?"))>>
End If>>
''Format the requested page (url) to have a ~ instead of the virtual path of the app>>
Dim appVirtualPath As String = app.Request.ApplicationPath>>
If requestedPage.Length >= appVirtualPath.Length Then>>
If requestedPage.Substring(0, appVirtualPath.Length).ToLower = appVirtualPath.ToLower Then>>
requestedPage = requestedPage.Substring(appVirtualPath.Length)>>
If requestedPage.Substring(0, 1) = "/" Then>>
requestedPage = "~" & requestedPage>>
Else>>
requestedPage = "~/" & requestedPage>>
End If>>
End If>>
End If>>
''Get the new path to rewrite the url to if it meets one>>
''of the defined virtual urls.>>
pathNew = config.MappedUrl(requestedPage)>>
''If the requested url matches one of the virtual one>>
''the lets go and rewrite it.>>
If pathNew.Length > 0 Then>>
If pathNew.IndexOf("?") > -1 Then>>
''The matched page has a querystring defined>>
If pathOld.IndexOf("?") > -1 Then>>
pathNew += "&" & Right(pathOld, pathOld.Length - pathOld.IndexOf("?") - 1)>>
End If>>
Else>>
''The matched page doesn't have a querystring defined>>
If pathOld.IndexOf("?") > -1 Then>>
pathNew += Right(pathOld, pathOld.Length - pathOld.IndexOf("?"))>>
End If>>
End If>>
''Rewrite to the new url>>
HttpContext.Current.RewritePath(pathNew)>>
End If>>
End If>>
End Sub>>
End Class>>
End Namespace>>
/Web.Config>>
<configuration>>>
<!-- Declare the custom 'RegExUrlMapping' section and handler -->>>
<configSections>>>
<sectionGroup name="system.web">>>
<section name="RegExUrlMapping" type="RegExUrlMapping_HTTPModule.RegExUrlMappingConfigHandler"/>>>
</sectionGroup>>>
</configSections>>>
<system.web> >>
<!-- Tell ASP.NET to use the RegEx URL Mapping HTTP Module -->>>
<httpModules>>>
<add type="RegExUrlMapping_HTTPModule.RegExUrlMappingModule" name="RegExUrlMappingModule"/>>>
</httpModules>>>
<!-- The RegEx URL Mapping parser goes through these in sequential order. -->>>
<RegExUrlMapping enabled="true"> >>
<add url="~/(.*)default\.aspx" mappedUrl="~/$1default.aspx" />>>
<add url="~/Chris.aspx" mappedUrl="~/Default.aspx?p=chris"/>>>
<add url="~/show(.*)\.aspx" mappedUrl="~/Default.aspx?p=$1&section=3"/>>>
</RegExUrlMapping>>>
</system.web>>>
</configuration>>>
>>
ASP.NET 1.1 Url Mapping code can be found here: http://pietschsoft.com/Blog/archive/2005/07/04/717.aspx>>
>Update 11/14/2005 - Scoth Guthrie has posted about why they didn't add Regular Expression support to the ASP.NET 2.0 URL Mapping on his blog. He has also posted a link to this blog entry in that blog post. It's pretty cool that my blog has gotten noticed by him.>
>http://weblogs.asp.net/scottgu/archive/2005/11/14/430493.aspx>