惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园 - 司徒正美
Jina AI
Jina AI
Microsoft Azure Blog
Microsoft Azure Blog
博客园 - 三生石上(FineUI控件)
宝玉的分享
宝玉的分享
MyScale Blog
MyScale Blog
I
InfoQ
爱范儿
爱范儿
Microsoft Security Blog
Microsoft Security Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
Stack Overflow Blog
Stack Overflow Blog
T
Tailwind CSS Blog
D
DataBreaches.Net
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
T
The Blog of Author Tim Ferriss
B
Blog
阮一峰的网络日志
阮一峰的网络日志
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
月光博客
月光博客
雷峰网
雷峰网
Recent Announcements
Recent Announcements
量子位
B
Blog RSS Feed

博客园 - 小罗

学习CRYPTO C#中使用网络函数 (第一部分 用户函数)[翻译] C#图片处理类 在WINCE或Mobile下面获取当前目录 (翻译)从底层了解ASP.NET体系结构 使用会话状态(一) 小技巧:ASP.NET中编程杀死进程 - 小罗 - 博客园 ASP.NET—From验证:全部代码及讲解 ASP.NET如何存取 SQLServer数据库图片 ASP.NET基本编程习惯 用asp.net还原与恢复sqlserver数据库 ASP.NET 2.0移动开发之定义设备筛选器 Session丢失原因与解决方案小结 小心!目录删除及重命名操作,一定丢失Session~~ C# 文件操作(上传 下载 删除 文件列表...) 40 种网页技巧 过滤ASP.NET输出HTML中的无用空格 在ASP.NET中创建安全的web站点(配置) ASP.NET Forums 页面模型分析
采用HttpModules来重写URLs
小罗 · 2008-01-21 · via 博客园 - 小罗

据说通过HttpModules可以将类似于:http://www.infotouch.cn/detail.aspx?id=120 的URL地址重写为:http://www.infotouch.cn/detail/120.aspx 。这样最直接的好处就是可以让搜索引擎搜索到页面,因为搜索引擎对?之后的参数不太理睬。

今天尝试了一下,发现一个需要注意的问题,就是HttpModules只能对特定扩展名的URL进行重写(注:只能对“映射”-“应用程序扩展”中指定交给Asp.Net处理的扩展名文件进行处理),从Google找了些英文资料,发现这种情况是由IIS处理请求的机理决定的。

IIS对于没有扩展名的URL处理请求的机理:

如果请求的路径(path)有扩展名,IIS首先查找是否已设定了对应的应用程序扩展,有则将控制权交给该应用程序:
所以对于 http://www.infotouch.cn/detail.aspx?id=120 这样的情况很容易处理,只要处理为 http://www.infotouch.cn/detail/120.aspx 即可。因为IIS根据*.aspx的扩展名将控制权交给了Asp.Net,进而转给了HttpModules。

如果请求的路径(path)没有扩展名,例如:http://www.infotouch.cn/detail 这样的路径。IIS首先检查该虚拟路径是否对应到一个本地目录,如果具有对应的本地目录,再查找该目录下是否具有缺省文件,如果找到,就重定向为该缺省文件的路径。否则,IIS报告一个Http404-文件未找到错误。

实践:

首先写一个处理URLs重写的类,并且这个类必须继承IHttpHandler接口,以博客园的程序为例:

public class UrlReWriteModule : System.Web.IHttpModule
{
     public void Init(HttpApplication context)
     {
        context.BeginRequest +=new EventHandler(context_BeginRequest);
     }

    public void Dispose()
    {
    }
}

UrlReWriteModule类就是处理URLs重写的类,继承IHttpHandler接口,实现该接口的两个方法,Init和Dispose。在Init方法里注册自己定义的方法,如上例所示:

content.BeginRequest +=new EventHandler(content_BeginRequest);

BeginRequest是一个事件,在收到新的Http请求时触发,content_BeginRequest就是触发时处理的方法。另外说明一点,HttpModules能注册的方法还有很多,如:EndRequest、Error、Disposed、PreSendRequestContent等等。

在content_BeginRequest方法中具体处理URLs重写的细节,比如,将 http://www.cnblogs.com/archive.aspx?user=rrooyy&id=56041 重写为 http://www.cnblogs.com/rrooyy/archive/2004/10/24/56041.html 。然后将重新生成的Url用HttpContext.RewritePath()方法重写即可,如下:

private void context_BeginRequest(object sender, EventArgs e)
{
     HttpContext context   = ((HttpApplication)sender).Context;
     // 获取旧的Url
     string url = context.Request.Path.ToLower();
     // 重新生成新的Url
     string newUrl = ...; // 具体过程略
     // 重写Url
     context.RewritePath(newUrl);
}

提醒:newUrl的格式不是http://www.infotouch.com/user/archive.aspx,而是从当前应用程序根目录算起的绝对路径,如:user\archive.aspx,这一点请特别注意。

最后要web.config中注册重写URLs的类,格式如下:

<HTTPMODULES>
    <ADD type="classname,assemblyname" name="modulename"/>
    <REMOVE name="modulename"/>
    <CLEAR />
</HTTPMODULES>

采用<ADD>标签可以注册一个类;<REMOVE>可以移除某个类,如果某个子目录不希望继承父目录的某个Http Module注册,就需要使用这个标签;<CLEAR />可以移除所有的Http Module注册。