如果我们运行上面的代码,并通过查看 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);
}
}
最后,我们来看一下在我们的重写模块程序集中的三个类:
在 web.config 中注册重写模块要使用重写模块,需要在配置文件中的 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"
Windows 2003 Server (IIS 6)
Default Web Site
然后在虚拟路径标签上点击 Configuration… 按钮 (或如果要使用整个站点都做映射就选择主目录标签)。
Windows XP (IIS 5)
Windows 2003 Server (IIS 6)
接下来,点击添加按钮,并输入一个扩展,你还需要指定一个 ASP.NET ISAPI 扩展,注意去掉选项的对勾以检查文件是否存在。