与 /Products/Beverages.aspx 相似,下面我们要为其他产品类别添加重写规则。此操作仅包括在 Web.config 文件的 <Rules> 元素内添加附加的 <rewriterrule> 元素。请参阅下载内容中的 Web.config 文件,以获取用于此演示的一组完整的重写规则。
为了使 URL 更具可删节性,最好使用户只需从 /Products/Beverages.aspx 中删除 Beverages.aspx 即可看到产品类别的列表。乍一看,这可能是一项很普通的任务(只需添加一个将 /Products/ 映射到 /ListCategories.aspx 的重写规则即可)。但此操作存在一个微妙之处,即您必须首先创建一个 /Products/ 目录,并在 /Products/ 目录中添加一个空的 Default.aspx 文件。
要理解需要执行这些额外步骤的原因,可以参考前面的内容,即 URL 重写引擎位于 ASP.NET 级别上。也就是说,如果 ASP.NET 引擎永远没有机会处理请求,URL 重写引擎就没有办法检测传入的 URL。而且,请记住,仅当被请求的文件具有相应的扩展名时,IIS 才会将传入请求传递给 ASP.NET 引擎。因此,如果用户访问 /Products/,而 IIS 没有看到任何文件扩展名,那么它将检查目录,以查看是否存在这样一个文件,即该文件名为默认文件名中的一个。(Default.aspx、Default.htm、Default.asp 等等。“IIS 管理”对话框中“Web 服务器属性”对话框的“文档”选项卡对这些默认文件名进行了定义。)当然,如果 /Products/ 目录不存在,IIS 将返回 HTTP 404 错误。
因此,我们需要创建 /Products/ 目录。另外,我们还需要在此目录中创建一个文件 Default.aspx。这样,当用户访问 /Products/ 时,IIS 将检测目录,查看是否存在一个名为 Default.aspx 的文件,然后将处理过程传递给 ASP.NET 引擎。然后,URL 重写器将在重写 URL 时分解。
创建目录和 Default.aspx 文件后,请继续操作,并向 <rules> 元素中添加以下重写规则:
<RewriterRule> <LookFor>~/Products/Default\.aspx</LookFor> <SendTo>~/ListCategories.aspx</SendTo></RewriterRule>
有了此规则之后,当用户访问 /Products/ 或 /Products/Default.aspx 时,他们将看到产品类别列表,如图 4 所示。
如果要重写的 URL 中包含一个服务器端的 Web 窗体并执行回发,则窗体回发后,将使用带下划线的 URL。也就是说,如果用户在浏览器中输入 /Products/Beverages.aspx,他们在浏览器地址栏中看到的将是 /Products/Beverages.aspx,但是他们看到的内容将是 ListProductsByCategory.aspx?CategoryID=1 的内容。如果 ListProductsByCategory.aspx 执行了回发,用户将被回发到 ListProductsByCategory.aspx?CategoryID=1,而不是 /Products/Beverages.aspx。这样不会中断任何内容,但从用户的角度考虑,如果单击按钮时突然看到 URL 更改会使他们感到不安。
出现这种情况的原因是:在呈现 Web 窗体时,它会将其操作属性直接设置为 Request 对象中文件路径的值。当然,在呈现 Web 窗体时,URL 已从 /Products/Beverages.aspx 重写为 ListProductsByCategory.aspx?CategoryID=1,这表明 Request 对象报告用户要访问 ListProductsByCategory.aspx?CategoryID=1。只需使服务器端窗体不呈现操作属性即可解决此问题。(默认情况下,如果窗体不包含操作属性,浏览器将会回发。)
不幸的是,web 窗体不允许您明确指定操作属性,也不允许您设置某些属性以