当前位置:编程学习 > C#/ASP.NET >>

一个完整的ASP.NET 2.0 URL重写方案[翻译]

答案:

这篇文章描述了一个完整的 ASP.NET 2.0 URL 重写方案。这个方案使用正则表达式来定义重写规则并解决通过虚拟 URLs 访问页面产生回发事件的一些可能的困难。

为什么要重写 URL ?

将 URL 重写方法应用到你的 ASP.Net 应用程序的两个主要原因是:可用性和可维护性。

可用性

谁都知道,相对于难于辨认的带参数的长的查询路径,用户更喜欢一些短的、简洁的 URL。任何时候,一个容易记住和敲入的路径比添加到收藏夹更有用。其次,当一个浏览器的收藏夹不可用时,记住的地址总比在搜索引擎中输入关键字进行搜索,然后再查找要强的多。比较下面的两个地址:

(1)

http://www.somebloghost.com/Blogs/Posts.aspx?Year=2006&Month=12&Day=10

(2)

http://www. somebloghost.com/Blogs/2006/12/10/

第一个 URL 包含了查询字符串;第二个URL包含的信息可以让用户清楚的看到他看的东西,它还可以使用户更容易的修改地址栏的内容,如:http://www.somehost.com/Blogs/2006/12/.

可维护性

在很多WEB应用程序中,开发人员经常会将页面从一个目录移到另一个目录,让我们假设一开始有两个可用页面: http://www.somebloghost.com/Info/Copyright.aspxhttp://www.somebloghost.com/Support/Contacts.aspx,但是后来开发者将 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>

这样,如果用户输入 http://www.somebloghost.com/Support/Contacts.aspx, 它将看到 http://www.somebloghost.com/Help/Contacts.aspx , 而他并不知道那个页已经移除。

这个方案对于只有两个页面被移到其它位置的情况是足够的。但它对有一打的需要重定位的页或者需要创建一个整洁的URL来说,它是不合适的。另一个使用Asp.Net 的原有的URL映射技术的不太好的地方是:如果 Contacts.aspx 页包含的元素在回发到服务器时(这是非常可能的), 用户将会惊奇的发现地址 http://www.somebloghost.com/Support/Contacts.aspx 却变成了 http://www.somebloghost.com/Help/Contacts.aspx

这是因为ASP.NET 引擎用页面的实际地址修改了表单formaction 属性 ,所以表单就变成了下面的样子:

<form name="formTest" method="post"
action="http://www.simple-talk.com/Help/Contacts.aspx" id="formTest">

</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>

这样,所有像: http://localhost/Web/2006/12/10/ 这样的请示,将会在内部将会用带参数的请求重定向到 Posts.aspx 。

请注意: web.config 是一个结构良好的 XML 文件, 它禁止在属性值中使用 & 符号,所以在例子中,应当使用 & 代替。

要在配置文件中使用这个重写模块,还需要注册节和指定处理模块,像下面这样增加一个configSections配置节:

 <configSections>

<sectionGroup name="modulesSection">

<section name="rewriteModule" 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>

另一个我们在开发重写模块过程中要做的就是还需要允许在虚拟路径中传递参数,象这样: http://www.somebloghost.com/2006/12/10/?Sort=Desc&SortBy=Date 。所以我们还需要有一个检测通过虚拟 URL 传递参数的解决方案

接下来让我们来创建类库。首先,我们要引用 System.Web 程序集,这样我们可以实现一些基于 web 特殊功能。如果要使我们的模块能够访问 web.config,还需要引用 System.Configuration 程序集。

处理配置节

要能处理 web.config 中的配置,我们必需创建一个实现了 IConfigurationSectionHandler 接口的类 (详情查看 MSDN )。如下:

using System;

using System.Collections.Generic;

using System.Text;

using System.Configuration;

using System.Web;

using System.Xml;

namespace RewriteModule

{

public class RewriteModuleSectionHandler : IConfigurationSectionHandler

{

private XmlNode _XmlSection;

private string _RewriteBase;

private bool _RewriteOn;

public XmlNode XmlSection

{

get { return _XmlSection; }

}

public string RewriteBase

{

get { return _RewriteBase; }

}

public bool RewriteOn

{

get { return _RewriteOn; }

}

public object Create(object parent,
object configContext,
System.Xml.XmlNode section)

{

// set base path for rewriting module to

// application root

_RewriteBase = HttpContext.Current.Request.ApplicationPath + "/";

// process configuration section

// from web.config

try

{

_XmlSection = section;

_RewriteOn = Convert.ToBoolean(
section.SelectSingleNode("rewriteOn").InnerText);

}

catch (Exception ex)

{

throw (new Exception("Error while processing RewriteModule
configuration section.", ex));

}

return this;

}

}

}<

上一个:asp.net 产生随机颜色实现代码
下一个:asp.net 不用GridView自带删除功能,删除一行数据

CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,