这篇文章描述了一个完整的 ASP.NET 2.0 URL 重写方案。这个方案使用正则表达式来定义重写规则并解决通过虚拟 URLs 访问页面产生回发事件的一些可能的困难。
为什么要重写 URL ?将 URL 重写方法应用到你的 ASP.Net 应用程序的两个主要原因是:可用性和可维护性。
可用性谁都知道,相对于难于辨认的带参数的长的查询路径,用户更喜欢一些短的、简洁的 URL。任何时候,一个容易记住和敲入的路径比添加到收藏夹更有用。其次,当一个浏览器的收藏夹不可用时,记住的地址总比在搜索引擎中输入关键字进行搜索,然后再查找要强的多。比较下面的两个地址:
(1) ?Year=2006&Month=12&Day=10 (2) somebloghost.com/Blogs/2006/12/10/
第一个 URL 包含了查询字符串;第二个URL包含的信息可以让用户清楚的看到他看的东西,它还可以使用户更容易的修改地址栏的内容,如:.
可维护性在很多WEB应用程序中,开发人员经常会将页面从一个目录移到另一个目录,让我们假设一开始有两个可用页面: 和 ,但是后来开发者将 Copyright.aspx 和 Contacts.aspx 移到了 Help 目录,用户收藏起来地址就需要重新定位。这个问题虽然可以简单的用 Response.Redirect(new location) 来解决,但是如果有成百上千的页面呢?应用程序中就会包含大量的无效链接。
使用 URL 重写,允许用户只需修改配置文件,这种方法可以让开发者将web应用程序逻辑结构与物理结构独立开来。
ASP.NET 2.0 中的原有的URL 映射ASP.NET 2.0 为 web 应用程序提供了一个开箱即用的映射静态 URL 的解决方案。这个方案不用编写代码就可以在 web.config 中将旧的 URLs 映射到新的地址。 要使用 URL 映射,只需在 web.config 文件的 system.web 节中创建一个新的 urlMappings 节 ,并添加要映射的地址 (“ ~/ ”指向应用程序的根目录):
<urlMappings enabled="true">
<add url="~/Info/Copyright.aspx" mappedUrl="~/Help/Copyright.aspx" />
<add url="~/Support/Contacts.aspx" mappedUrl="~/Help/Contacts.aspx" />
</urlMappings>
这样,如果用户输入 , 它将看到 , 而他并不知道那个页已经移除。
这个方案对于只有两个页面被移到其它位置的情况是足够的。但它对有一打的需要重定位的页或者需要创建一个整洁的URL来说,它是不合适的。另一个使用Asp.Net 的原有的URL映射技术的不太好的地方是:如果 Contacts.aspx 页包含的元素在回发到服务器时(这是非常可能的), 用户将会惊奇的发现地址 却变成了
。 这是因为ASP.NET 引擎用页面的实际地址修改了表单form 的 action 属性 ,所以表单就变成了下面的样子:
<form method="post"
action="http://www.simple-talk.com/Help/Contacts.aspx">
</form>
这样看来,URL 映射在ASP.NET 2.0 中几乎是无用的。我们应当能够使用一个映射规则来指定一系列相似的 URL。最好的解决方案就是使用正则表达式 ( Wikipedia 上可以查看概览,and 在 .NET 下的实现可以查看 MSDN), 但由于 ASP.NET 2.0 映射不支持正则表达式,所以我们需要开发一个内建到 URL 映射的不同的方案- URL 重写模块。 最好的方法就是创建一个可重用的、简单的配置模块来实现,显然我们应创建一个 HTTP 模块 (关于 HTTP 模块的详细信息请查看 MSDN 杂志) 并在独立的程序集中实现。要使这个程序集简单易用,我们应实现这个重写引擎的可配置性,即能够在 web.config 中指定规则。
在开发过程中,我们应能使这个重写模块打开或关闭 (比如你有一个较难捕获的bug,而它可能是由不正确的重写模块引起的)这样在 web.config 中对重写模块的配置节进行打开或关闭就成为一个选择。这样,在 web.config 中,一个配置节的示例如下:
<rewriteModule>
<rewriteOn>true</rewriteOn>
<rewriteRules>
<rule source="(\d+)/(\d+)/(\d+)/"
destination="Posts.aspx?Year=$1&Month=$2&Day=$3"/>
<rule source="(.*)/Default.aspx"
destination="Default.aspx?Folder=$1"/>
</rewriteRules>
</rewriteModule>
这样,所有像: 这样的请示,将会在内部将会用带参数的请求重定向到 Posts.aspx 。
请注意: web.config 是一个结构良好的 XML 文件, 它禁止在属性值中使用 & 符号,所以在例子中,应当使用 & 代替。
要在配置文件中使用这个重写模块,还需要注册节和指定处理模块,像下面这样增加一个configSections配置节:
<configSections><sectionGroup>
<section type="RewriteModule.
RewriteModuleSectionHandler, RewriteModule"/>
</sectionGroup>
</configSections>
这样你就可以在 configSections 节的后面这样使用了:
<modulesSection>
<rewriteModule>
<rewriteOn>true</rewriteOn>
<rewriteRules>
<rule source="(\d+)/(\d+)/(\d+)/" destination="Post.aspx?Year=$1&Month=$2&Day=$3"/>
<rule source="(.*)/Default.aspx" destination="Default.aspx?Folder=$1"/>
</rewriteRules>
</rewriteModule>
</modulesSection>