手机
当前位置:查字典教程网 >编程开发 >asp.net教程 >Community Server专题三:HttpModule
Community Server专题三:HttpModule
摘要:从专题三开始分析CommunityServer的一些具体的技术实现,根据IIS对请求的处理流程,从HttpModule&HttpHandle...

从专题三开始分析CommunityServer的一些具体的技术实现,根据IIS对请求的处理流程,从HttpModule& HttpHandler切入话题,同时你也可以通过一系列的专题了解CS的运行过程,不只如此,所有的.Net1.1构架的WebApp都是以同样的顺序执行的。

先了解一下IIS系统。它是一个程序,负责对网站的内容进行管理并且处理对客户的请求做出反应。当用户对一个页面提出请求时,IIS做如下反应(不考虑权限问题):

1.把对方请求的虚拟路径转换成物理路径

2.根据物理路径搜索请求的文件

3.找到文件后,获取文件的内容

4.生成Http头信息。

5.向客户端发送所有的文件内容:首先是头信息,然后是Html内容,最后是其它文件的内容。

6.客户端IE浏览器获得信息后,解析文件内容,找出其中的引用文件,如.js.css.gif等,向IIS请求这些文件。

7.IIS获取请求后,发送文件内容。

8.当浏览器获取所有内容后,生成内容界面,客户就看到图像/文本/其它内容了。

但是IIS本身是不支持动态页面的,也就是说它仅仅支持静态html页面的内容,对于如.asp,.aspx,.cgi,.php等,IIS并不会处理这些标记,它就会把它当作文本,丝毫不做处理发送到客户端。为了解决这个问题。IIS有一种机制,叫做ISAPI的筛选器,这个东西是一个标准组件(COM组件),当在在访问IIS所不能处理的文件时,如asp.net1.1中的IIS附加ISAPI筛选器如图:

Asp.net 服务在注册到IIS的时候,会把每个扩展可以处理的文件扩展名注册到IIS里面(如:*.ascx、*.aspx等)。扩展启动后,就根据定义好的方式来处理IIS所不能处理的文件,然后把控制权跳转到专门处理代码的进程中。让这个进程开始处理代码,生成标准的HTML代码,生成后把这些代码加入到原有的 Html中,最后把完整的Html返回给IIS,IIS再把内容发送到客户端。

有上面对ISAPI的简单描述,我们把HttpModule&HttpHandler分开讨论,并且结合CS进行具体的实现分析。

HttpModule:

HttpModule实现了ISAPIFilter的功能,是通过对IhttpModule接口的继承来处理。下面打开CS中的CommunityServerComponents项目下的CSHttpModule.cs文件(放在HttpModule目录)

//------------------------------------------------------------------------------

//<copyrightcompany="TelligentSystems">

//Copyright(c)TelligentSystemsCorporation.Allrightsreserved.

//</copyright>

//------------------------------------------------------------------------------

usingSystem;

usingSystem.IO;

usingSystem.Web;

usingCommunityServer.Components;

usingCommunityServer.Configuration;

namespaceCommunityServer

{

//*********************************************************************

//CSHttpModule

//

/**////<summary>

///ThisHttpModuleencapsulatesalltheforumsrelatedeventsthatoccur

///duringASP.NETapplicationstart-up,errors,andendrequest.

///</summary>

//***********************************************************************/

publicclassCSHttpModule:IHttpModule

{

Membervariablesandinheritedproperties/methods#regionMembervariablesandinheritedproperties/methods

publicStringModuleName

{

get{return"CSHttpModule";}

}

//*********************************************************************

//ForumsHttpModule

//

/**////<summary>

///InitializestheHttpModuleandperformsthewireupofallapplication

///events.

///</summary>

///<paramname="application">Applicationthemoduleisbeingrunfor</param>

publicvoidInit(HttpApplicationapplication)

{

//Wire-upapplicationevents

//

application.BeginRequest+=newEventHandler(this.Application_BeginRequest);

application.AuthenticateRequest+=newEventHandler(Application_AuthenticateRequest);

application.Error+=newEventHandler(this.Application_OnError);

application.AuthorizeRequest+=newEventHandler(this.Application_AuthorizeRequest);

//settingsID=SiteSettingsManager.GetSiteSettings(application.Context).SettingsID;

Jobs.Instance().Start();

//CSExceptionex=newCSException(CSExceptionType.ApplicationStart,"AppicationStarted"+AppDomain.CurrentDomain.FriendlyName);

//ex.Log();

}

//intsettingsID;

publicvoidDispose()

{

//CSExceptionex=newCSException(CSExceptionType.ApplicationStop,"ApplicationStopping"+AppDomain.CurrentDomain.FriendlyName);

//ex.Log(settingsID);

Jobs.Instance().Stop();

}

Installer#regionInstaller

#endregion

#endregion

ApplicationOnError#regionApplicationOnError

privatevoidApplication_OnError(Objectsource,EventArgse)

{

HttpApplicationapplication=(HttpApplication)source;

HttpContextcontext=application.Context;

CSExceptioncsException=context.Server.GetLastError()asCSException;

if(csException==null)

csException=context.Server.GetLastError().GetBaseException()asCSException;

try

{

if(csException!=null)

{

switch(csException.ExceptionType)

{

caseCSExceptionType.UserInvalidCredentials:

caseCSExceptionType.AccessDenied:

caseCSExceptionType.AdministrationAccessDenied:

caseCSExceptionType.ModerateAccessDenied:

caseCSExceptionType.PostDeleteAccessDenied:

caseCSExceptionType.PostProblem:

caseCSExceptionType.UserAccountBanned:

caseCSExceptionType.ResourceNotFound:

caseCSExceptionType.UserUnknownLoginError:

caseCSExceptionType.SectionNotFound:

csException.Log();

break;

}

}

else

{

Exceptionex=context.Server.GetLastError();

if(ex.InnerException!=null)

ex=ex.InnerException;

csException=newCSException(CSExceptionType.UnknownError,ex.Message,context.Server.GetLastError());

System.Data.SqlClient.SqlExceptionsqlEx=exasSystem.Data.SqlClient.SqlException;

if(sqlEx==null||sqlEx.Number!=-2)//don'tlogtimeouts

csException.Log();

}

}

catch{}//notmuchtodohere,butwewanttopreventinfiniteloopingwithourerrorhandles

CSEvents.CSException(csException);

}

#endregion

ApplicationAuthenticateRequest#regionApplicationAuthenticateRequest

privatevoidApplication_AuthenticateRequest(Objectsource,EventArgse)

{

HttpContextcontext=HttpContext.Current;

Providerp=null;

ExtensionModulemodule=null;

//Iftheinstallerismakingtherequestterminateearly

if(CSConfiguration.GetConfig().AppLocation.CurrentApplicationType==ApplicationType.Installer){

return;

}

//Onlycontinueifwehaveavalidcontext

//

if((context==null)||(context.User==null))

return;

try

{

//Logictohandlevariousauthenticationtypes

//

switch(context.User.Identity.GetType().Name.ToLower())

{

//Microsoftpassport

case"passportidentity":

p=(Provider)CSConfiguration.GetConfig().Extensions["PassportAuthentication"];

module=ExtensionModule.Instance(p);

if(module!=null)

module.ProcessRequest();

else

gotodefault;

break;

//Windows

case"windowsidentity":

p=(Provider)CSConfiguration.GetConfig().Extensions["WindowsAuthentication"];

module=ExtensionModule.Instance(p);

if(module!=null)

module.ProcessRequest();

else

gotodefault;

break;

//Forms

case"formsidentity":

p=(Provider)CSConfiguration.GetConfig().Extensions["FormsAuthentication"];

module=ExtensionModule.Instance(p);

if(module!=null)

module.ProcessRequest();

else

gotodefault;

break;

//Custom

case"customidentity":

p=(Provider)CSConfiguration.GetConfig().Extensions["CustomAuthentication"];

module=ExtensionModule.Instance(p);

if(module!=null)

module.ProcessRequest();

else

gotodefault;

break;

default:

CSContext.Current.UserName=context.User.Identity.Name;

break;

}

}

catch(Exceptionex)

{

CSExceptionforumEx=newCSException(CSExceptionType.UnknownError,"ErrorinAuthenticateRequest",ex);

forumEx.Log();

throwforumEx;

}

////Gettherolestheuserbelongsto

////

//Rolesroles=newRoles();

//roles.GetUserRoles();

}

#endregion

ApplicationAuthorizeRequest#regionApplicationAuthorizeRequest

privatevoidApplication_AuthorizeRequest(Objectsource,EventArgse){

if(CSConfiguration.GetConfig().AppLocation.CurrentApplicationType==ApplicationType.Installer)

{

//CSContext.Create(context);

return;

}

HttpApplicationapplication=(HttpApplication)source;

HttpContextcontext=application.Context;

CSContextcsContext=CSContext.Current;

//boolenableBannedUsersToLogin=CSContext.Current.SiteSettings.EnableBannedUsersToLogin;

////Iftheinstallerismakingtherequestterminateearly

//if(csContext.ApplicationType==ApplicationType.Installer){

//return;

//}

//csContext.User=CSContext.Current.User;

CSEvents.UserKnown(csContext.User);

ValidateApplicationStatus(csContext);

//Trackanonymoususers

//

Users.TrackAnonymousUsers(context);

//Doweneedtoforcetheusertologin?

//

if(context.Request.IsAuthenticated)

{

stringusername=context.User.Identity.Name;

if(username!=null)

{

string[]roles=CommunityServer.Components.Roles.GetUserRoleNames(username);

if(roles!=null&&roles.Length>0)

{

csContext.RolesCacheKey=string.Join(",",roles);

}

}

}

}

#endregion

ApplicationBeginRequest#regionApplicationBeginRequest

privatevoidApplication_BeginRequest(Objectsource,EventArgse)

{

HttpApplicationapplication=(HttpApplication)source;

HttpContextcontext=application.Context;

CSConfigurationconfig=CSConfiguration.GetConfig();

//Iftheinstallerismakingtherequestterminateearly

if(config.AppLocation.CurrentApplicationType==ApplicationType.Installer)

{

//CSContext.Create(context);

return;

}

CheckWWWStatus(config,context);

CSContext.Create(context,ReWriteUrl(context));

}

privatevoidCheckWWWStatus(CSConfigurationconfig,HttpContextcontext)

{

if(config.WWWStatus==WWWStatus.Ignore)

return;

conststringwithWWW="http://www.";

conststringnoWWW="http://";

stringrawUrl=context.Request.Url.ToString().ToLower();

boolisWWW=rawUrl.StartsWith(withWWW);

if(config.WWWStatus==WWWStatus.Remove&&isWWW)

{

context.Response.Redirect(rawUrl.Replace(withWWW,noWWW));

}

elseif(config.WWWStatus==WWWStatus.Require&&!isWWW)

{

context.Response.Redirect(rawUrl.Replace(noWWW,withWWW));

}

}

ReWriteUrl#regionReWriteUrl

privateboolReWriteUrl(HttpContextcontext)

{

//we'renowallowingeachindividualapplicationtobeturnedonandoffindividually.Sobeforeweallow

//arequesttogothroughweneedtocheckifthisproductisdisabledandthepathisforthedisabledproduct,

//ifsowedisplaythedisabledproductpage.

//

//I'malsoallowingthepagerequesttogothroughifthepagerequestisforanadminpage.Inthepastifyou

//disabledtheforumsyouwerelockedout,nowwiththischeck,evenifyou'renotonthesamemachinebutyou'reaccessing

//anadminpaththerequestwillbeallowedtoproceed,wheretherestofthecheckswillensurethattheuserhasthe

//permissiontoaccessthespecificurl.

//UrlRewriting

//

//RewriteUrl(context);

stringnewPath=null;

stringpath=context.Request.Path;

boolisReWritten=SiteUrls.RewriteUrl(path,context.Request.Url.Query,outnewPath);

//verywachky.ThefirstcallintoReWritePathalwaysfailswitha404.

//callingReWritePathtwiceactuallyfixestheprobelmaswell.Instead,

//weusethesecondReWritePathoverloadanditseemstowork100%

//ofthetime.

if(isReWritten&&newPath!=null)

{

stringqs=null;

intindex=newPath.IndexOf('?');

if(index>=0)

{

qs=(index<(newPath.Length-1))?newPath.Substring(index+1):string.Empty;

newPath=newPath.Substring(0,index);

}

context.RewritePath(newPath,null,qs);

}

returnisReWritten;

}

#endregion

privatevoidValidateApplicationStatus(CSContextcntx)

{

if(!cntx.User.IsAdministrator)

{

stringdisablePath=null;

switch(cntx.Config.AppLocation.CurrentApplicationType)

{

caseApplicationType.Forum:

if(cntx.SiteSettings.ForumsDisabled)

disablePath="ForumsDisabled.htm";

break;

caseApplicationType.Weblog:

if(cntx.SiteSettings.BlogsDisabled)

disablePath="BlogsDisabled.htm";

break;

caseApplicationType.Gallery:

if(cntx.SiteSettings.GalleriesDisabled)

disablePath="GalleriesDisabled.htm";

break;

caseApplicationType.GuestBook:

if(cntx.SiteSettings.GuestBookDisabled)

disablePath="GuestBookDisabled.htm";

break;

caseApplicationType.Document://新增ugoer

if(cntx.SiteSettings.DocumentDisabled)

disablePath="DocumentsDisabled.htm";

break;

}

if(disablePath!=null)

{

stringerrorpath=cntx.Context.Server.MapPath(string.Format("~/Languages/{0}/errors/{1}",cntx.Config.DefaultLanguage,disablePath));

using(StreamReaderreader=newStreamReader(errorpath))

{

stringhtml=reader.ReadToEnd();

reader.Close();

cntx.Context.Response.Write(html);

cntx.Context.Response.End();

}

}

}

}

#endregion

}

}

在Web.Config中的配置:

<httpModules>

<addname="CommunityServer"type="CommunityServer.CSHttpModule,CommunityServer.Components"/>

<addname="Profile"type="Microsoft.ScalableHosting.Profile.ProfileModule,MemberRole,Version=1.0.0.0,Culture=neutral,PublicKeyToken=b7c773fb104e7562"/>

<addname="RoleManager"type="Microsoft.ScalableHosting.Security.RoleManagerModule,MemberRole,Version=1.0.0.0,Culture=neutral,PublicKeyToken=b7c773fb104e7562"/>

</httpModules>

CSHttpModule.csUML:

要实现HttpModule功能需要如下步骤:

1.编写一个类,实现IhttpModule接口

2.实现Init方法,并且注册需要的方法

3.实现注册的方法

4.实现Dispose方法,如果需要手工为类做一些清除工作,可以添加Dispose方法的实现,但这不是必需的,通常可以不为Dispose方法添加任何代码。

5.在Web.config文件中,注册您编写的类

到这里我们还需要了解一个Asp.Net的运行过程:

在图中第二步可以看到当请求开始的时候,马上就进入了HttpModule,在CS中由于实现了HttpModule的扩展CSHttpModule.cs 类,因此当一个web请求发出的时候(如:一个用户访问他的blog),CS系统首先调用CSHttpModule.cs类,并且进入

publicvoidInit(HttpApplicationapplication)

该方法进行初始化事件:

application.BeginRequest+=newEventHandler(this.Application_BeginRequest);

application.AuthenticateRequest+=newEventHandler(Application_AuthenticateRequest);

application.Error+=newEventHandler(this.Application_OnError);

application.AuthorizeRequest+=newEventHandler(this.Application_AuthorizeRequest);

有事件就要有对应的处理方法:

privatevoidApplication_BeginRequest(Objectsource,EventArgse)

privatevoidApplication_AuthenticateRequest(Objectsource,EventArgse)

privatevoidApplication_OnError(Objectsource,EventArgse)

privatevoidApplication_AuthorizeRequest(Objectsource,EventArgse)

事件被初始化后就等待系统的触发,请求进入下一步此时系统触发Application_BeginRequest事件,事件处理内容如下:

privatevoidApplication_BeginRequest(Objectsource,EventArgse)

{

HttpApplicationapplication=(HttpApplication)source;

HttpContextcontext=application.Context;

CSConfigurationconfig=CSConfiguration.GetConfig();

//Iftheinstallerismakingtherequestterminateearly

if(config.AppLocation.CurrentApplicationType==ApplicationType.Installer)

{

//CSContext.Create(context);

return;

}

CheckWWWStatus(config,context);

CSContext.Create(context,ReWriteUrl(context));

}

privatevoidCheckWWWStatus(CSConfigurationconfig,HttpContextcontext)

{

if(config.WWWStatus==WWWStatus.Ignore)

return;

conststringwithWWW="http://www.";

conststringnoWWW="http://";

stringrawUrl=context.Request.Url.ToString().ToLower();

boolisWWW=rawUrl.StartsWith(withWWW);

if(config.WWWStatus==WWWStatus.Remove&&isWWW)

{

context.Response.Redirect(rawUrl.Replace(withWWW,noWWW));

}

elseif(config.WWWStatus==WWWStatus.Require&&!isWWW)

{

context.Response.Redirect(rawUrl.Replace(noWWW,withWWW));

}

}

ReWriteUrl#regionReWriteUrl

privateboolReWriteUrl(HttpContextcontext)

{

//we'renowallowingeachindividualapplicationtobeturnedonandoffindividually.Sobeforeweallow

//arequesttogothroughweneedtocheckifthisproductisdisabledandthepathisforthedisabledproduct,

//ifsowedisplaythedisabledproductpage.

//

//I'malsoallowingthepagerequesttogothroughifthepagerequestisforanadminpage.Inthepastifyou

//disabledtheforumsyouwerelockedout,nowwiththischeck,evenifyou'renotonthesamemachinebutyou'reaccessing

//anadminpaththerequestwillbeallowedtoproceed,wheretherestofthecheckswillensurethattheuserhasthe

//permissiontoaccessthespecificurl.

//UrlRewriting

//

//RewriteUrl(context);

stringnewPath=null;

stringpath=context.Request.Path;

boolisReWritten=SiteUrls.RewriteUrl(path,context.Request.Url.Query,outnewPath);

//verywachky.ThefirstcallintoReWritePathalwaysfailswitha404.

//callingReWritePathtwiceactuallyfixestheprobelmaswell.Instead,

//weusethesecondReWritePathoverloadanditseemstowork100%

//ofthetime.

if(isReWritten&&newPath!=null)

{

stringqs=null;

intindex=newPath.IndexOf('?');

if(index>=0)

{

qs=(index<(newPath.Length-1))?newPath.Substring(index+1):string.Empty;

newPath=newPath.Substring(0,index);

}

context.RewritePath(newPath,null,qs);

}

returnisReWritten;

}

#endregion

这个事件主要做两个事情

a:为发出请求的用户初始化一个Context,初始化Context用到了线程中本地数据槽(LocalDataStoreSlot),把当前用户请求的上下文(contextb)保存在为此请求开辟的内存中。

b:判断是否需要重写URL(检查是否需要重写的过程是对SiteUrls.config文件中正则表达式和对应Url处理的过程),如果需要重写URL,就执行asp.net级别上的RewritePath方法获得新的路径,新的路径才是真正的请求信息所在的路径。这个专题不是讲URLRewrite,所以只要明白URL在这里就进行Rewrite就可以了,具体的后面专题会叙述。

处理完 Application_BeginRequest后进程继向下执行,随后触发了Application_AuthenticateRequest(如果有朋友不明白这个执行过程,可以通过调试中设置多个断点捕获事件执行的顺序。如果你还不会调试,可以留言偷偷的告诉我,嘿嘿。), Application_AuthenticateRequest事件初始化一个context的Identity,其实CS提供了很多的 Identity支持,包括Microsoftpassport,但是目前的版本中使用的是默认值 System.Web.Security.FormsIdentity。具体代码如下:

privatevoidApplication_AuthenticateRequest(Objectsource,EventArgse)

{

HttpContextcontext=HttpContext.Current;

Providerp=null;

ExtensionModulemodule=null;

//Iftheinstallerismakingtherequestterminateearly

if(CSConfiguration.GetConfig().AppLocation.CurrentApplicationType==ApplicationType.Installer){

return;

}

//Onlycontinueifwehaveavalidcontext

//

if((context==null)||(context.User==null))

return;

try

{

//Logictohandlevariousauthenticationtypes

//

switch(context.User.Identity.GetType().Name.ToLower())

{

//Microsoftpassport

case"passportidentity":

p=(Provider)CSConfiguration.GetConfig().Extensions["PassportAuthentication"];

module=ExtensionModule.Instance(p);

if(module!=null)

module.ProcessRequest();

else

gotodefault;

break;

//Windows

case"windowsidentity":

p=(Provider)CSConfiguration.GetConfig().Extensions["WindowsAuthentication"];

module=ExtensionModule.Instance(p);

if(module!=null)

module.ProcessRequest();

else

gotodefault;

break;

//Forms

case"formsidentity":

p=(Provider)CSConfiguration.GetConfig().Extensions["FormsAuthentication"];

module=ExtensionModule.Instance(p);

if(module!=null)

module.ProcessRequest();

else

gotodefault;

break;

//Custom

case"customidentity":

p=(Provider)CSConfiguration.GetConfig().Extensions["CustomAuthentication"];

module=ExtensionModule.Instance(p);

if(module!=null)

module.ProcessRequest();

else

gotodefault;

break;

default:

CSContext.Current.UserName=context.User.Identity.Name;

break;

}

}

catch(Exceptionex)

{

CSExceptionforumEx=newCSException(CSExceptionType.UnknownError,"ErrorinAuthenticateRequest",ex);

forumEx.Log();

throwforumEx;

}

////Gettherolestheuserbelongsto

////

//Rolesroles=newRoles();

//roles.GetUserRoles();

}

再下来是Application_AuthorizeRequest事件被触发,事件代码如下:

privatevoidApplication_AuthorizeRequest(Objectsource,EventArgse){

if(CSConfiguration.GetConfig().AppLocation.CurrentApplicationType==ApplicationType.Installer)

{

//CSContext.Create(context);

return;

}

HttpApplicationapplication=(HttpApplication)source;

HttpContextcontext=application.Context;

CSContextcsContext=CSContext.Current;

//boolenableBannedUsersToLogin=CSContext.Current.SiteSettings.EnableBannedUsersToLogin;

////Iftheinstallerismakingtherequestterminateearly

//if(csContext.ApplicationType==ApplicationType.Installer){

//return;

//}

//csContext.User=CSContext.Current.User;

CSEvents.UserKnown(csContext.User);

ValidateApplicationStatus(csContext);

//Trackanonymoususers

//

Users.TrackAnonymousUsers(context);

//Doweneedtoforcetheusertologin?

//

if(context.Request.IsAuthenticated)

{

stringusername=context.User.Identity.Name;

if(username!=null)

{

string[]roles=CommunityServer.Components.Roles.GetUserRoleNames(username);

if(roles!=null&&roles.Length>0)

{

csContext.RolesCacheKey=string.Join(",",roles);

}

}

}

}

在Application_AuthorizeRequest中分析关键几行代码:

1:CSContextcsContext=CSContext.Current;//该代码取出在前一个事件中保存在LocalDataStoreSlot中的Context,说明白点就是从内存中取出之前保存的一些数据。

2: CSEvents.UserKnown(csContext.User);//这里触发了一个UserKnown事件,涉及到CS中大量使用委托与事件的一个类CSApplication(CSApplication.cs文件),后续对这个类做专题分析,这里只要先了解该事件起到判断登陆用户是否 ForceLogin以及登录的帐户是否是禁用就可以了(把对user的判断移入Application_AuthorizeRequest事件处理程序中是很好的一种处理方法)

3:ValidateApplicationStatus(csContext);//判断论坛、blog、相册是否被禁用,如果登录用户的角色不为IsAdministrator,就跳转到相应的禁用警告页面,如Blog被禁用即跳转到 BlogsDisabled.htm页面显示。

4:Users.TrackAnonymousUsers(context);//如果是匿名用户,在这个方法中跟踪记录。

处理完上面三个事件后,CS将开始处理请求页面中的具体业务逻辑,如果用户请求的是登录页面,接下来就处理登录页面需要的业务逻辑和呈现,当然这里还会触发一系列其他事件,因为这些事件没有在这里定义我们暂时不做考虑。要说明一点,HttpModule在整个web请求到响应完成过程中都没有退出进程,而是处于监控状态。Application_OnError正是处于其监控范围下的一个事件,一旦有Exception或者继承Exception的类被异常抛出,HttpModule就捕获它,之后就可以根据Exception中ExceptionType值统一处理这些不同的错误信息。CS中就是这样实现错误处理的,具体的我们看一下代码:

privatevoidApplication_OnError(Objectsource,EventArgse)

{

HttpApplicationapplication=(HttpApplication)source;

HttpContextcontext=application.Context;

CSExceptioncsException=context.Server.GetLastError()asCSException;

if(csException==null)

csException=context.Server.GetLastError().GetBaseException()asCSException;

try

{

if(csException!=null)

{

switch(csException.ExceptionType)

{

caseCSExceptionType.UserInvalidCredentials:

caseCSExceptionType.AccessDenied:

caseCSExceptionType.AdministrationAccessDenied:

caseCSExceptionType.ModerateAccessDenied:

caseCSExceptionType.PostDeleteAccessDenied:

caseCSExceptionType.PostProblem:

caseCSExceptionType.UserAccountBanned:

caseCSExceptionType.ResourceNotFound:

caseCSExceptionType.UserUnknownLoginError:

caseCSExceptionType.SectionNotFound:

csException.Log();

break;

}

}

else

{

Exceptionex=context.Server.GetLastError();

if(ex.InnerException!=null)

ex=ex.InnerException;

csException=newCSException(CSExceptionType.UnknownError,ex.Message,context.Server.GetLastError());

System.Data.SqlClient.SqlExceptionsqlEx=exasSystem.Data.SqlClient.SqlException;

if(sqlEx==null||sqlEx.Number!=-2)//don'tlogtimeouts

csException.Log();

}

}

catch{}//notmuchtodohere,butwewanttopreventinfiniteloopingwithourerrorhandles

CSEvents.CSException(csException);

}

当抛出Exception后,CS开始处理Application_OnError,根据抛出的Exception的ExceptionType类型不同做不同的处理(ForumExceptionType.cs中定义所有的CSExceptionType)。随后调用Log()保存错误信息到数据库中,以便管理员跟踪这些错误的原因。这里还有重要的一句:CSEvents.CSException(csException)它触发了2个事件类 CSCatastrophicExceptionModule与CSExceptionModule中的处理程序,与 Application_AuthorizeRequest中UserKnown处理机制是一样的,会在以后的专题讨论。只要知道这里会执行 RedirectToMessage方法,把页面重新定向到一个友好的错误显示页即可,如下图所示:

至此,CSHttpModule类已经全部分析完毕。在CS里还有另外两个HttpModule,属于Membership范畴,由于CS引用的是 Membership的程序集无非进行内部的运行细节分析,但是工作原理与CSHttpModule是一致的,当你真正理解CSHttpModule的时候要去分析其他HttpModule也就不在话下了。希望我的这些分析能对你有帮助。

原文地址:http://www.cnblogs.com/ugoer/archive/2005/09/06/230917.html

【Community Server专题三:HttpModule】相关文章:

asp.net字符串分割函数使用方法分享

SQL Server 2005安装过程中出现错误的解决办法

浏览器窗口滚动加载数据采用异步形式从后台加载数据

在.net中用CheckBoxList实现单选

SqlDataSource 链接Access 数据

ASP.NET 2.0下的条件编译

ASP.NET 2.0写无限级下拉菜单

.Net 2.0 原汁原味读取注册表

gridview调整单元格宽度的方法

asp.net遍历目录文件夹和子目录所有文件

精品推荐
分类导航