如果我们运行上面的代码,并通过查看 ASP.NET 的 HTML 源代码 的 action 会发现,它竟然包含了一个 ASP.NET 的实际路径页。例如,我们使用页 ~/Posts.aspx 来处理像 somebloghost.com/Blogs/2006/12/10/Default.aspx 的请求, 发现 action="/Posts.aspx"。这意味着用户并没有使用虚拟路径进行回发,而是使用了实际的 somebloghost.com/Blog.aspx. 这个并不是我们需要的。所以,需要加一段代码来处理这些不希望的结果。
首先,我们要在 HttpModule 注册和实现一个另外的方法:
public void Init(HttpApplication context)
{
// it is necessary to
context.BeginRequest += new EventHandler(
RewriteModule_BeginRequest);
context.PreRequestHandlerExecute += new EventHandler(
RewriteModule_PreRequestHandlerExecute);
}
void RewriteModule_PreRequestHandlerExecute(object sender, EventArgs e)
{
HttpApplication app = (HttpApplication)sender;
if ((app.Context.CurrentHandler is Page) &&
app.Context.CurrentHandler != null)
{
Page pg = (Page)app.Context.CurrentHandler;
pg.PreInit += new EventHandler(Page_PreInit);
}
}
这个方法检查用户是否请求了一个正常的 ASP.NET 页,然后为该页的 PreInit 事件增加处理过程。这儿 RewriteContext 将处理实际参数,然后二次重写URL。二次重写是必需的,以使 ASP.NET 能够在它的表单的action属性中使用一个虚拟路径。
void Page_PreInit(object sender, EventArgs e)
{
// restore internal path to original
// this is required to handle postbacks
if (HttpContext.Current.Items.Contains("OriginalUrl"))
{
string path = (string)HttpContext.Current.Items["OriginalUrl"];
// save query string parameters to context
RewriteContext con = new RewriteContext(
HttpContext.Current.Request.QueryString, path);
HttpContext.Current.Items["RewriteContextInfo"] = con;
if (path.IndexOf("?") == -1)
path += "?";
HttpContext.Current.RewritePath(path);
}
}
最后,我们来看一下在我们的重写模块程序集中的三个类:
![Figure 2 一个完整的ASP.NET 2.0 URL重写方案[翻译]](/uploads/allimg/200613/04311O608_0.gif)
要使用重写模块,需要在配置文件中的 httpModules 节注册重写模块,如下:
<httpModules>
<add type="RewriteModule.RewriteModule, RewriteModule"/>
</httpModules>
使用重写模块在使用重写模块时,需要注意:
在 web.config 中来使用一些特殊字符是不可能的,因为它是一个结构良好的 XML 文件,因此,你只能用 HTML 编码的字符代替,如:使用 & 代替 &。 要在你的 ASPX 中使用相对路径,需要在HTML标签调用 ResolveUrl 方法,如: <img src="https://www.jb51.net/<%=ResolveUrl("~/Images/Test.jpg")%>" />。 Bear in mind the greediness of regular expressions and put rewriting rules to web.config in order of their greediness, for instance: <rule source="Directory/(.*)/(.*)/(.*)/(.*).aspx"destination="Directory/Item.aspx?
Source=$1&Year=$2&ValidTill=$3&Sales=$4"/>
<rule source="Directory/(.*)/(.*)/(.*).aspx"
destination="Directory/Items.aspx?
Source=$1&Year=$2&ValidTill=$3"/>
<rule source="Directory/(.*)/(.*).aspx"
destination="Directory/SourceYear.aspx?
Source=$1&Year=$2&"/>
<rule source="Directory/(.*).aspx"
destination="Directory/Source.aspx?Source=$1"/> 如果你要在页面中使用 RewriteModule 而不使用 .aspx,就必须在 IIS 中进行配置以使用期望的扩展映射到请求页,如下节所述: IIS 配置: 使用带扩展的重写模块代替 .aspx
要使用带扩展的重写模块代替 .aspx (如 .html or .xml), 必须配置 IIS ,以使这些扩展映射到 ASP.NET 引擎 (ASP.NET ISAPI 扩展)。要进行这些设置,需要以管理员身份登录。
打开 IIS 管理控制台,并选择你要配置的站点的虚拟路径:
Windows XP (IIS 5)
Virtual Directory "RW"
![一个完整的ASP.NET 2.0 URL重写方案[翻译]](/uploads/allimg/200613/04311Y515_0.gif)
Windows 2003 Server (IIS 6)
Default Web Site
![一个完整的ASP.NET 2.0 URL重写方案[翻译]](https://www.jb51.net/upload/2009-11/20091126181944169.gif)
然后在虚拟路径标签上点击 Configuration… 按钮 (或如果要使用整个站点都做映射就选择主目录标签)。
Windows XP (IIS 5)
![一个完整的ASP.NET 2.0 URL重写方案[翻译]](/uploads/allimg/200613/04311W950_0.gif)
Windows 2003 Server (IIS 6)
![一个完整的ASP.NET 2.0 URL重写方案[翻译]](/uploads/allimg/200613/04311b536_0.gif)
接下来,点击添加按钮,并输入一个扩展,你还需要指定一个 ASP.NET ISAPI 扩展,注意去掉选项的对勾以检查文件是否存在。
![一个完整的ASP.NET 2.0 URL重写方案[翻译]](/uploads/allimg/200613/04311aJ2_0.gif)
