ASP.NET中httpModules的用法和配置
这个东西有嘛用?
个人理解类似一个拦截器吧,简而言之就是所有页面执行之前,都会先执行httpModules中所配置的类.
用途的话,个人多用于 伪静态重写,登录与否的权限判断,用户的权限判断等等吧.
总之,可以理解为不管访问你网站中的哪个页面,都会先去执行httpModules中的类中的Init方法.
假如要实现一个这样的功能:实现目录式伪静态重写.
先解释一下啥叫目录式伪静态重写:伪静态就不说了,都知道.
目录式的就是比如:http://www.aaa.com/a/b/c/d/155,像这样的地址难道真的认为在主域名下还存在这个二级域名(目录级)吗?php里面好像常用的地址重写格式就是这样的.但是在.net中,我个人常用的两个重写组件是:
1.ISAPRewrite 这个是在IIS上配置一个ISAPI筛选器,本地需要安装的
2.Intelligencia.UrlRewriter.dll 这个是在web.config中配置一些对应规则,这个就是一个DLL,引用进来就行
拿第二种方式举例吧,假如web.config中有一条对应规则是:<rewrite url="index-(\d+)-(\d+).html" to="index.aspx?id=$1&pid=$2" processing="stop"/>
那么访问index-1-2.html其实就等于访问了index.aspx?id=1&pid=2
假如今天你们老板发羊癫疯叫你把所有的格式换成index/1/2(这个就是目录式),那么还按照那样的套路去配置,肯定报错404了
反正我是没有用以上的任何一个组件实现过这种目录式伪静态方式,如果有实现过的,还请指教
其实可以用httpModules的办法去处理这种问题的,原理就不赘述了,上面都有写
说一下配置方法吧:
第一步:在网站根目录下建一个文件夹,再在这个文件夹下加一个TransferUtility.cs,类名随便怎么起,这个类要继承 IHttpModule接口,并且要显式实现接口中的两个方法(很重要),代码片段:
public class TransferUtility : IHttpModule { #region IHttpModule 成员 public void Dispose()//显式实现接口中的方法 { } public void Init(HttpApplication context)//显式实现接口中的方法 { context.BeginRequest += new EventHandler(context_BeginRequest); } #region IHttpModule 成员 private void context_BeginRequest(object sender, EventArgs e) { //doSomething 主要就是这里面的代码了,方法体在下面在详述 }
第二步:在Web.config的<system.web></system.web>节点之间添加一个HttpModule节点,代码片段:
<system.web> <httpModules> <add name="Transfer" type="yourNamespace.TransferUtility" /> <!-- 有必要要解释一下两个参数name和type的作用和注意点. name,不用管了 你爱咋咋地 如果你有雅兴,把自己的名字弄上去也是个不错的主意 type,很重要,你要是取错了,你就挂了。这个属性直接关系到程序是否能加载到这个类.
yourNamespace.TransferUtility的含义为: yourNamespace是这个类的命名空间,后面是刚刚加的那个TransferUtility的类名.
--> </httpModules> </system.web>
接下来就是context_BeginRequest方法体的实现了:
private void context_BeginRequest(object sender, EventArgs e) { HttpApplication application = (HttpApplication)sender; HttpContext context = HttpContext.Current; string absUri = context.Request.Url.AbsoluteUri;//获取地址栏的路径 if(!string.IsNullOrEmpty(absUri)) { if(absUri.Contains("/a/b/c/d"))//判读地址是否包含这个字符串, { context.Server.Transfer(@"~/index.aspx");//用Transfer跳转页面,地址栏是不会有变化的,注意:这个路径一定要写对,如果没写对,就会报一个很蛋疼的错误:执行index.aspx子请求时出错,你调都没办法调,不信的话可以试试,直接弄死你,搞半天最后是路径搞错了,不仅蛋疼,老板不爽还会狂屌你一顿 } if(absUri.Contains("/a/b/c/d/e/f/g/1/2"))//带参数的情况,如果有参数可以用正则把地址字符串割出来,对应到index.aspx?id=1&pid=2..... { int id ,pid=0; //此处用正则割出参数的值,代码省略 context.Server.Transfer(string.Format(@"~/index.aspx?id={0}&pid={1}",id,pid));//用Transfer跳转页面,地址栏是不会有变化的,路径,别怪我没提醒你,注意路径 } } }
现在假如访问这个地址:http://localhost:7674/a/b/c/d/e/f/g/1/2,就相当于访问了index.aspx?id=1&pid=2.
访问方式,完全不需要发布到IIS,用VS的虚拟环境就可以调试的, 方法是:直接页面名>右键>在浏览器中查看....然后就是等。。。什么?页面没打开?没关系,去打杯水,再和你左边那个2B青年扯一下皮,千万别去碰你的电脑,也不要用手去扣你的脚趾头,即使你一个星期没洗很脏了。
前面那一大串都是伪装出来的,你爱怎么弄就怎么弄,好了,1分钟后,相信你看到效果出来了,没看到就是你人品有问题了,真的,不用怀疑的,不信你拿镜子照照
还有最后一点就是:注意图片路径,因为浏览器会把图片地址解析成http://localhost:7674/a/b/c/d/e/f/g/1/2/images/aa.jpg。很明显这个地址是不存在,所以图片一定要用绝对路径,比如<img src="http://localhost:7674/images/aa.jpg">
Thanks for your watching!