NULL

快乐的活着...【四分之一的精力献给了工作,四分之三的精力献给了女人...】

  博客园 :: 首页 :: 新随笔 ::  :: 订阅 订阅 :: 管理 ::
  37 随笔 :: 1 文章 :: 1131 评论 :: 42 Trackbacks
 

初窥asp.net Runtime之二

上篇地址http://www.cnblogs.com/wmj/archive/2008/03/03/1088298.html
    上一篇中,通过实现
IHttpModule接口,就看到网页上输出了两句话,这是怎么回事呢?先别急,通过反射,先看看HttpApplication到底定义了那些事件!

My god,这么多事件!

在此,先弄清楚一个先后顺序问题,向IHttpModule订阅的事件处理方法,并不一定优先于IHttpHandler的方法先执行,比如IHttpHandler.ProcessRequest方法优先于IHttpModule.EndRequest事件处理方法,这很明显!在HttpModule中的主要任务就是向HttpApplication发出订阅,至于订阅的处理方法,什么时候执行,得看请求执行到了哪里,所以如果要实现自定义的IHttpModule,只要做两件事;订阅和实现订阅的处理方法!(谢谢Cat Chen的提醒)

在上一篇中,我只实现了BeginRequestEndRequest方法,看看系统中是怎样定义的
// 摘要:
//     ASP.NET 响应请求时作为 HTTP 执行管线链中的第一个事件发生。
EndRequest定义
// 摘要:
//     ASP.NET 响应请求时作为 HTTP 执行管线链中的最后一个事件发生。

至于HttpApplication的其他方法,在后面的环节中再说。

    这时候,突然想到一件事,那时我刚接触网络,朋友帮我申请了一个免费的空间,我做了一个人主页放到空间里!出了一怪事(当时认为),在我的个人主页的页眉和页脚上,莫名其妙的被别人加上了一些情色广告!当时很纳闷,怎么也弄不掉那些广告,但是查看html的源文件,压根看不到任何异常的demo!后来才知道运营商为了自己的利益,在IHttpModule模块上做了手脚!

 (HttpModule应用)还是动手做一个Moduled的例子吧!

曾经看到园子中有朋友,在自定义的Module中,订阅了授权事件HttpApplication.OnAuthorizeRequest,然后在授权事件的处理方法中,从Session[“key”]集合中获取用户标识ID,并和当前请求的用户标识ID比较,如果与Session[“key”]集合中的用户标识ID相同,就授权,不同或者没有用户标识ID,就不授权!当然,这种基于URL授权的想法不错!

但是,有几点需要考虑到!(说明不是针对那为朋友,只是找个案例罢了......)
    
一,OnAuthorizeRequest事件的处理方法中,session集合还没有生成,又怎能取值呢

    
二,从数据库中查找用户ID,性能肯定有损耗,有人可能会想到,我只在登录的时候查询一次数据库,然后保存起来,哈哈,不过还是有点麻烦,因为此时cachesession等都不能用,只有application可以使用,难道把用户ID保存在HttpApplication对象里吗?(HttpApplication不是隔离的,怎感觉不妥)

三,解决办法,目前只是猜想,哈哈,思路是这样的!
HttpApplication. OnAuthorizeRequest事件的处理方法之前,或者之中,想办法提前获取请求关联的状态,这里指会话状态(session)!哈哈

现在,我就在OnAuthorizeRequest事件的处理方法中,做一些简单的处理,判断请求的类型,如果不为get或者post类型,就终止这个Http管道中的其他事件,直接跳到EndRequest事件!

配置,就不说了

class AuthorHttpModule : System.Web.IHttpModule//, IRequiresSessionState
{
    
public AuthorHttpModule()
    
{ }
    
public void Init(System.Web.HttpApplication application)
    
{
        
application.AuthorizeRequest += new EventHandler(this.OnAuthorize);
        
application.AcquireRequestState += new EventHandler(application_AcquireRequestState);
    
}
    
public void OnAuthorize(Object sender,EventArgs e)
    
{
        
HttpApplication application = (HttpApplication)sender;
        
HttpContext context = application.Context;
        
HttpRequest request = context.Request;
        
HttpResponse response = context.Response;
        
string type = request.HttpMethod;
        
if (type.ToLower() == "get" || type.ToLower() == "post")
        
{ }
        
else
        
{
            
application.CompleteRequest();
            
response.StatusCode = 500;
            
response.StatusDescription = "SORRY,Request's type must be Get or Post!";
        
}
        
HttpApplicationState app1=context.Application;
        
HttpApplicationState app2 = application.Application;
        
App1["app1"] = "appValue1";
        
App2["app2"] = "appValue2";
        
HttpSessionState sessionState = context.Session;
        
//sessionState["ss1"] = "sss";//here ,throw Exception object
    
}
    
void application_AcquireRequestState(object sender, EventArgs e)
    
{
        
HttpApplication application = (HttpApplication)sender;
        HttpContext context = application.Context;
        HttpRequest request = context.Request;
        HttpResponse response = context.Response;
        HttpSessionState sessionState = context.Session;
        sessionState["ss"] = "ssValue";
    }
    public void Dispose()
    { }
}

说明;
    一,application.CompleteRequest()方法终止这个Http管道中的其他事件,直接跳到EndRequest事件!然后设置响应的状态代码为500

二,HttpApplicationState app1=context.ApplicationHttpApplicationState app2 = application.Application;方法都是获取服务器的HttpApplicationState集合!而且,在授权事件中可以获取或者设置,但是HttpSessionState集合不行!(但是在AcquireRequestState事件中可以获取或者设置HttpSessionState集合)!

最后;

    虽然application.CompleteRequest()方法终止了Http管道中的其他事件,直接跳到EndRequest事件,但是后面的application.PreSendRequestHeadersapplication.PreSendRequestContent事件仍然会执行,不信试试!    
    虽然我们自定义了自己的Module,但并不会覆盖系统默认的Module,顺序是先系统的,后自己定义的,如果想完全清除系统的Module,在configremove掉对应的项就OK

    有不妥之处,还望指教!

posted on 2008-03-05 09:16 王孟军! 阅读(2376) 评论(12)  编辑 收藏 所属分类: asp.net

评论

#1楼  2008-03-05 09:57 XX0XX [未注册用户]
太好了,又来了,继续收藏~
  回复  引用    

#2楼  2008-03-05 09:57 Cat Chen      
public的事件,就没必要通过反射来看吧,MSDN都有所记录的。
  回复  引用  查看    

#3楼  2008-03-05 11:32 Superstone      
没看明白代码要干什么。。。。实现IRequiresSessionState接口就可以使用session了,你代码里也有写啊。
  回复  引用  查看    

#4楼 [楼主] 2008-03-05 11:41 王孟军!      
@Superstone

在IHttpModule中无需要实现IRequiresSessionState接口,
session只有在IHttpModule.AcquireRequestState 事件被激活之后,才能使用,并是只要实现了IRequiresSessionState接口就可以使用Session的
  回复  引用  查看    

#5楼  2008-03-06 16:18 Superstone      
@王孟军!
搞错了搞错了,和IHttpHandler搞混了。
  回复  引用  查看    

#6楼 [楼主] 2008-03-06 16:32 王孟军!      
@Superstone
5楼的大哥,到底是谁弄错了?

只有在实现IHttpHandler的时候,才需要继承IRequiresSessionState接口,
IRequiresSessionState接口是一个标记,标记继承了它的类才能对Session读写
  回复  引用  查看    

#7楼  2008-05-18 15:06 Zhuang miao      
大哥,把你页面的背景音乐调下吧。。。老听容易崩溃啊!!!读文章需要安静~~~求您了!!!
  回复  引用  查看    

#8楼  2008-06-07 22:24 chunfeng      
大哥,你写错了吧,
根本没有IHttpApplication接口,而是HttpApplication类,写的时候仔细推敲一下呀,不要发错误的文章上来
  回复  引用  查看    

#9楼 [楼主] 2008-06-07 22:30 王孟军!      
@chunfeng
请仔细看清楚,我哪个地方说有
IHttpApplication接口,如果有,请指教
谢谢
  回复  引用  查看    

#10楼  2008-08-19 22:01 bingdian3721      
楼主啊,
先不说你这个"IHttpApplication"的上下文环境啊

不过确实是出现了.在正文第三行:

"IHttpApplication接口到底定义了那些事件!"

不能说没有吧
  回复  引用  查看    

#11楼 [楼主] 2008-08-20 08:58 王孟军!      
@bingdian3721
@chunfeng
抱歉,写快了,
是类,不是接口,抱歉,谢谢提醒
  回复  引用  查看    


标题  
姓名  
主页
Email (只有博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2008-08-20 08:58 编辑过


相关链接: