asp.net Forums 之HttpHandler和HttpModule

我们先说说IHttpHandler和IHttpModule这两个接口。
微软的解释为:
IHttpHandler: 定义 ASP.NET 为使用自定义 HTTP 处理程序同步处理 HTTP Web 请求而实现的协定。 
IHttpModule: 向继承类提供模块初始化和处置事件。 
有点看不懂,微软的解释一向如此。

那我们来看看代码:
public interface IHttpHandler
{
 bool IsReusable { get; }
 void ProcessRequest(HttpContext context);
}
IsReusable获取一个值,该值指示其他请求是否可以使用 System.Web.IHttpHandler 实例。
ProcessRequest()方法是处理请求的,System.Web.HttpContext 对象,它提供对用于为 HTTP 请求提供服务的内部服务器对象(如 Request、Response、Session 和 Server)的引用。

public interface IHttpModule
{
 void Dispose();
 void Init(HttpApplication context);
}

Dispose()方法用于释放资源。
Init()方法初始化这个HttpApplication,你可以在这时注册各类事件,如:Application_BeginRequest,Application_AuthenticateRequest,Application_OnError等。

那IHttpHandler与IHttpModule有什么区别呢:
1.先后次序.先IHttpModule,后IHttpHandler. 注:Module要看你响应了哪个事件,一些事件是在Handler之前运行的,一些是在Handler之后运行的
2.对请求的处理上:
IHttpModule是属于大小通吃类型,无论客户端请求的是什么文件,都会调用到它;例如aspx,rar,html的请求.
IHttpHandler则属于挑食类型,只有ASP.net注册过的文件类型(例如aspx,asmx等等)才会轮到调用它.
3.IHttpHandler按照你的请求生成响应的内容,IHttpModule对请求进行预处理,如验证、修改、过滤等等,同时也可以对响应进行处理    HttpHandler是HTTP请求的处理中心,真正地对客户端请求的服务器页面做出编译和执行,并将处理过后的信息附加在HTTP请求信息流中再次返回到HttpModule中。
    HttpHandler与HttpModule不同,一旦定义了自己的HttpHandler类,那么它对系统的HttpHandler的关系将是“覆盖”关系。

接下来,我们再来看看ANF中的IHttpModule和IHttpHandler。
ForumsHttpModule类是ANF中自定义的HttpModule,它位于AspNetForums命名空间下。
在这个HttpModule中,自定义了

 

代码
   
     
/// <summary>
/// 应用程序初始化
/// </summary>
/// <param name="application"></param>
public void Init(HttpApplication application)
{
// Wire-up application events
//
application.BeginRequest += new EventHandler( this .Application_BeginRequest);
application.AuthenticateRequest
+= new EventHandler(Application_AuthenticateRequest);
application.Error
+= new EventHandler( this .Application_OnError);
application.AuthorizeRequest
+= new EventHandler( this .Application_AuthorizeRequest);

#if DEBUG
application.ReleaseRequestState
+= new EventHandler( this .Application_ReleaseRequestState);
#endif

ForumConfiguration forumConfig
= ForumConfiguration.GetConfig();
if (forumConfig != null
&& forumConfig.IsBackgroundThreadingDisabled == false )
{
if (emailTimer == null )
emailTimer
= new Timer( new TimerCallback(ScheduledWorkCallbackEmailInterval), application.Context, EmailInterval, EmailInterval);

if (forumConfig.IsIndexingDisabled == false
&& statsTimer == null )
{
statsTimer
= new Timer( new TimerCallback(ScheduledWorkCallbackStatsInterval), application.Context, StatsInterval, StatsInterval);
}
}
}

 

 


应用程序错误处理 Application_OnError

 

代码
   
     
private void Application_OnError(Object source, EventArgs e)
{
ForumConfiguration forumConfig
= ForumConfiguration.GetConfig();
string defaultLanguage = forumConfig.DefaultLanguage;
HttpApplication application
= (HttpApplication) source;
HttpContext context
= application.Context;
ForumException forumException;
string html;
StreamReader reader;
// 增加异常信息不同级别显示--开始
// 如果为管理员,显示异常详细信息 by venjiang 2004-11-3
// 发布时注释此代码
// if(Users.GetUser().IsAdministrator)
// {
// context.Response.Write(context.Server.GetLastError().Message);
// return;
// }

// 增加异常信息不同级别显示--结束

if (context.Server.GetLastError().GetBaseException() is ForumException)
{
forumException
= (ForumException) context.Server.GetLastError().GetBaseException();

switch (forumException.ExceptionType)
{
case ForumExceptionType.DataProvider:

// We can't connect to the data store
//
reader = new StreamReader(context.Server.MapPath( " ~/Languages/ " + defaultLanguage + " /errors/DataStoreUnavailable.htm " ));
html
= reader.ReadToEnd();
reader.Close();

html
= html.Replace( " [DATASTOREEXCEPTION] " , forumException.Message);
context.Response.Write(html);
context.Response.End();
break ;

case ForumExceptionType.UserInvalidCredentials:
forumException.Log();
break ;

case ForumExceptionType.AccessDenied:
forumException.Log();
break ;

case ForumExceptionType.AdministrationAccessDenied:
forumException.Log();
break ;

case ForumExceptionType.ModerateAccessDenied:
forumException.Log();
break ;

case ForumExceptionType.PostDeleteAccessDenied:
forumException.Log();
break ;

case ForumExceptionType.PostProblem:
forumException.Log();
break ;

case ForumExceptionType.UserAccountBanned:
forumException.Log();
break ;

// LN 6/9/04: New exception added
case ForumExceptionType.ResourceNotFound:
// context.Response.Write(context.Server.GetLastError().Message);
forumException.Log();
break ;

case ForumExceptionType.UserUnknownLoginError:
forumException.Log();
break ;
}
}
else
{
forumException
= new ForumException(ForumExceptionType.UnknownError, context.Server.GetLastError().Message, context.Server.GetLastError());
forumException.Log();
}

if (forumException.ExceptionType == ForumExceptionType.UnknownError)
{
if ((context.IsCustomErrorEnabled) && ( ! context.Request.Url.IsLoopback))
ForumContext.RedirectToMessage(context, forumException);
}
else
{
// context.Response.Write(context.Server.GetLastError().Message);
ForumContext.RedirectToMessage(context, forumException);
}
}

 

 

当安全模块已建立用户标识时发生 Application_AuthenticateRequest

 

代码
   
     
private void Application_AuthenticateRequest(Object source, EventArgs e)
{
HttpContext context
= HttpContext.Current;
Provider p
= null ;
ExtensionModule module
= null ;

// Only continue if we have a valid context
//
if ((context == null ) || (context.User == null ))
return ;


try
{
// Logic to handle various authentication types
//
switch (context.User.Identity.AuthenticationType.ToLower())
{
// Microsoft passport
case " passport " :
p
= (Provider) ForumConfiguration.GetConfig().Extensions[ " PassportAuthentication " ];
module
= ExtensionModule.Instance(p);

module.ProcessRequest();
break ;

// Windows
case " negotiate " :
p
= (Provider) ForumConfiguration.GetConfig().Extensions[ " WindowsAuthentication " ];
module
= ExtensionModule.Instance(p);

module.ProcessRequest();
break ;

default :
ForumContext.Current.UserName
= context.User.Identity.Name;
break ;

}

}
catch (Exception ex)
{
ForumException forumEx
= new ForumException(ForumExceptionType.UnknownError, " Error in AuthenticateRequest " , ex);
forumEx.Log();

throw forumEx;
}

// 获取用户角色
Roles roles = new Roles();
roles.GetUserRoles();
}

 

 

验证用户授权 Application_AuthorizeRequest

 

代码
   
     
private void Application_AuthorizeRequest(Object source, EventArgs e)
{
HttpApplication application
= (HttpApplication) source;
HttpContext context
= application.Context;

// Track anonymous users
//
Users.TrackAnonymousUsers();

// Do we need to force the user to login?
//
if (Users.GetUser().ForceLogin)
{
Moderate.ToggleUserSettings(ModerateUserSetting.ToggleForceLogin, Users.GetUser(),
0 );
context.Response.Redirect(Globals.GetSiteUrls().Logout,
true );
}


}

 

 

响应应用程序请求开始事件 Application_BeginRequest

 

代码
   
     
private void Application_BeginRequest(Object source, EventArgs e)
{
if (HttpContext.Current.Request.Path.IndexOf( ' \\ ' ) >= 0 ||
Path.GetFullPath(HttpContext.Current.Request.PhysicalPath)
!= HttpContext.Current.Request.PhysicalPath)
{
throw new HttpException( 404 , " not found " );
}

// 2005-6-25
// 阻止IP访问

//

try
{
HttpApplication application
= (HttpApplication) source;
HttpContext context
= application.Context;

if (application == null
|| context == null )
return ;

// Url Rewriting

string newPath = null ;
string path = context.Request.Path;
string query = context.Request.Url.Query;
bool isReWritten = RewriteUrl(path, query, out newPath);

if (isReWritten && newPath != null )
context.RewritePath(newPath);

ForumContext frmContext
= CreateForumContext(context);
frmContext.CurrentUrl
= context.Request.RawUrl.ToString();


// 2005/04/07
// safe to set url rewrite data;
if (isReWritten && newPath != null )
{
frmContext.IsUrlReWritten
= true ;
}

// Capture any pingback information
//
CaptureForumPingback();

// Are the forums disabled?
//
if ((Globals.GetSiteSettings().ForumsDisabled) && (HttpContext.Current.Request.Url.Host != " localhost " ))
{
ForumConfiguration forumConfig
= ForumConfiguration.GetConfig();
string defaultLanguage = forumConfig.DefaultLanguage;

// Forums is disabled
//
StreamReader reader = new StreamReader(context.Server.MapPath( " ~/Languages/ " + defaultLanguage + " /errors/ForumsDisabled.htm " ));
string html = reader.ReadToEnd();
reader.Close();

context.Response.Write(html);
context.Response.End();

}
}
catch (Exception ex)
{
ForumException forumEx
= new ForumException(ForumExceptionType.UnknownError, " Unknown error in BeginRequest " , ex);
forumEx.Log();
}

if (HttpContext.Current.Request.Path.ToLower().IndexOf( " msgs/default " ) < 0 )
{
if (BlockedIpAddresses.AddressIsBlocked(Globals.IPAddress))
throw new ForumException(ForumExceptionType.BlockedIpAddress);
}


}

 

 

等事件。
在Web.Config文件中配置

 

  
    
<!-- 指定应用程序HttpModule -->
< httpModules >
< add name = " AspNetForums " type = " AspNetForums.ForumsHttpModule, AspNetForums.Components " />
</ httpModules >

 

 

AvatarHttpHandler类是ANF中的自定义HttpHandler,它位于AspNetForums.Components.HttpHandler命名空间下。
这个HttpHandler主要用于处理用户头像的处理。

 

代码
   
     
public void ProcessRequest(HttpContext context)
{
try
{
Avatar userAvatar
= Resources.GetAvatar( int .Parse(context.Request.QueryString[ " UserID " ]));

context.Response.ContentType
= userAvatar.ContentType;
context.Response.OutputStream.Write(userAvatar.Content,
0 , userAvatar.Length);

context.Response.Cache.SetCacheability(HttpCacheability.Public);
// Terry Denham 7/16/2004
// changing default cache for avatars from 1 day to 30 minutes
context.Response.Cache.SetExpires(DateTime.Now.AddMinutes( 10 ));
context.Response.Cache.SetAllowResponseInBrowserHistory(
true );
context.Response.Cache.SetValidUntilExpires(
true );
context.Response.Cache.VaryByParams[
" UserID " ] = true ;
}
catch
{
}

}

 

 


在Web.Config文件中的配置。

代码
   
     
<!-- 指定应用程序HttpHandlers -->
< httpHandlers >
< add verb = " GET " path = " avatar.aspx " type = " AspNetForums.Components.HttpHandler.AvatarHttpHandler, AspNetForums.Components " />
< add verb = " GET " path = " vcard.aspx " type = " AspNetForums.Components.HttpHandler.VCardHttpHandler, AspNetForums.Components " />

 

 注: 本文引用了网络上的一些资料。

你可能感兴趣的:(asp.net)