public abstract class BaseModuleRewriter : IHttpModule{public virtual void Init(HttpApplication app){// 警告!此代码不适用于 Windows 身份验证!// 如果使用 Windows 身份验证,// 请改为 app.BeginRequestapp.AuthorizeRequest += newEventHandler(this.BaseModuleRewriter_AuthorizeRequest);}public virtual void Dispose() {}protected virtual void BaseModuleRewriter_AuthorizeRequest(object sender, EventArgs e){HttpApplication app = (HttpApplication) sender;Rewrite(app.Request.Path, app);}protected abstract void Rewrite(string requestedPath,HttpApplication app);}
请注意,BaseModuleRewriter 类将在 AuthorizeRequest 事件中执行 URL 重写。如上所述,如果将 Windows 身份验证与文件授权结合使用,您需要对此做出更改,以便可以在 BeginRequest 或 AuthenticateRequest 事件中执行 URL 重写。
ModuleRewriter 类扩展了 BaseModuleRewriter 类,并负责执行实际的 URL 重写。ModuleRewriter 包含单一覆盖方法(Rewrite()),如下所示:
protected override void Rewrite(string requestedPath,System.Web.HttpApplication app){// 获得配置规则RewriterRuleCollection rules =RewriterConfiguration.GetConfig().Rules;// 遍历每个规则for(int i = 0; i < rules.Count; i++){// 获得要查找的模式,并且// 解析 Url(转换为相应的目录)string lookFor = "^" +RewriterUtils.ResolveUrl(app.Context.Request.ApplicationPath,rules[i].LookFor) + "$";// 创建 regex(请注意,已设置 IgnoreCase)Regex re = new Regex(lookFor, RegexOptions.IgnoreCase);// 查看是否找到了匹配的规则if (re.IsMatch(requestedPath)){// 找到了匹配的规则 -- 进行必要的替换string sendToUrl =RewriterUtils.ResolveUrl(app.Context.Request.ApplicationPath,re.Replace(requestedPath, rules[i].SendTo));// 重写 URLRewriterUtils.RewriteUrl(app.Context, sendToUrl);break; // 退出 For 循环}}}
Rewrite() 方法从获取 Web.config 文件中的一组重写规则开始。然后,它将遍历重写规则,每次遍历一个,对于每个规则,它将获取规则的 LookFor 属性,并使用正则表达式来确定是否在被请求的 URL 中找到了匹配的规则。
如果找到了匹配的规则,将在具有 SendTo 属性值的被请求路径上执行正则表达式替换。然后,替换后的 URL 将被传递到 RewriterUtils.RewriteUrl() 方法中。RewriterUtils 是一个 helper 类,此类将提供一对由 URL 重写 HTTP 模块和 HTTP 处理程序使用的静态方法。RewriterUrl() 方法仅调用 HttpContext 对象的 RewriteUrl() 方法。
注意:您可能已注意到,执行正则表达式匹配和替换时,将调用 RewriterUtils.ResolveUrl()。此 helper 方法只替换具有应用程序路径值的字符串中的所有 ~ 实例。
URL 重写引擎的整个代码可随本文下载。我们已经介绍了大部分密切相关的组件,但还有一些其他组件(例如,对 Web.config 文件中 XML 格式的重写规则进行反序列化以使其成为对象的类),以及用于 URL 重写的 HTTP 处理程序工厂。本文剩余的三个部分将对 URL 重写的实际使用情况进行介绍。
返回页首为了实际演示 URL 重写引擎,我们来构建一个使用简单 URL 重写的 ASP.NET Web 应用程序。假设我们所工作的公司通过网络销售分类产品。这些产品分为以下几个类别:
类别 ID | 类别名称 |
1 | 饮料 |
2 | 调味品 |
3 | 糖果 |
4 | 奶制品 |
假