您的位置:首页 > 理论基础 > 计算机网络

DotNetNuke 5 C#版本解读之2--HTTP Modules

2010-07-21 02:43 375 查看
如果你是个asp.net新手建议你看看前面这部分,因为它会向你介绍什么是httpmodule,以及其他的一些概念。我想通过你读这篇文章来明白asp.net的机制,明白一些深层次的东西。我试着让大家我写的东西时不仅仅是跟着我去做某件事,而是了解了它。甚至去了解为什么要去做这件事。废话太多了。。。
在进入主题httpmodule之前需要你先了解几个概念,HTTPPipeline.维基百科上对它的解释如下:
HTTPpipeliningisatechniqueinwhichmultipleHTTPrequestsarewrittenouttoasinglesocketwithoutwaitingforthecorrespondingresponses.PipeliningisonlysupportedinHTTP/1.1,notin1.0.
Thepipeliningofrequestsresultsinadramaticimprovement[citationneeded]inpageloadingtimes,especiallyoverhighlatencyconnectionssuchassatelliteInternetconnections.
SinceitisusuallypossibletofitseveralHTTPrequestsinthesameTCPpacket,HTTPpipeliningallowsfewerTCPpacketstobesentoverthenetwork,reducingnetworkload.
Non-idempotentmethodslikePOSTshouldnotbepipelined.SequencesofGETandHEADrequestscanbealwayspipelined.AsequenceofotheridempotentrequestslikeGET,HEAD,PUTandDELETEcanbepipelinedornotdependingonwhetherrequestsinthesequencedependontheeffectofothers.[1]
HTTPpipeliningrequiresboththeclientandtheservertosupportit.HTTP/1.1conformingserversarerequiredtosupportpipelining.Thisdoesnotmeanthatserversarerequiredtopipelineresponses,butthattheyarerequirednottofailifaclientchoosestopipelinerequests.
http://en.wikipedia.org/wiki/HTTP_pipelining
说白了就是不需要等待服务器的回应向服务器发送多个http请求,它大大降低了页面的加载时间。
Asp.net提供了好几种方式来实现httppipeline。其中用的比较广泛的就是我们这里所说的httpModule,一种用户自定义组件方式。
如果你英文好点建议你看如下这个链接来了解下HTTPPipeline和httpmodule,
http://msdn.microsoft.com/en-us/magazine/cc301362.aspx
http://msdn.microsoft.com/en-us/library/ms178473(v=VS.80).aspx
如果想看着舒服点的中文建议你看如下这位大哥写的介绍http请求处理流程的文章:
http://en.wikipedia.org/wiki/HTTP_pipelining
HttpHandler的介绍:
http://www.tracefact.net/Asp-Net-Architecture/Introduction-to-Http-Handler.aspx
以及HTTPModule的介绍:
http://www.tracefact.net/Asp-Net/Introduction-to-Http-Module.aspx
里面包含了很多例子。你可以边看边学。而且讲得也非常好。
如果你认真看完了上面的内容我相信你已经了解了HTTPModule的作用。你也会了解了.net的项目中Global.asax是干嘛的了。大致的请求流程如下图:




DNN中HTTPModules的演变和HTTPModule的事件
现在我们来看DNN的源代码有一部分叫做HttpModules。



其实DNN之前的版本也是把httpmodules都放在了global.asax.vb里面(因为之前都是vb版本)。后来把这些模块给放到httpmodule单独这个模块了。原因如下:

管理员可以在系统中添加/移除这些模块,因为本身是个module。

开发人员可以能够在不修改主程序也就是DNN.liabrary的情况下可以修改或者替换这些HTTPmodules。

给大家提供了一个扩展HTTPPipeline的模板。因为你可以自己加上自己的HTTPModule

上面我提供的参考文章里也有介绍.netframework自带的一些httpmodule都在.netframewrok下有个config文件里放着,我们扩展后的HTTPModule也需要在DNN的web.config中配置:



我们知道HTTPModule都是继承了IhttpModule这个接口。



在Init方法中我们为context的某个事件来个委托。
HTTPModule的事件分为三种

应用程序执行之前发生。

主要有:
BeginRequest:每次程序向服务器发送请求它都会被触发。
AuthenticateRequest:表示请求准备好服务器端的认证,认证模式下使用
AuthorizeRequest:表示请求准备好服务器端授权。
ResolveRequestCache:在OutputCache模块中通过使用缓存让请求更短。
AcquireReuqestState:表示能获得请求前的状态。
PreRequesthandlerExecute:在程序的http请求发生前你可以触发的最后一个事件。
应用程序执行之后发生:
PostRequestHandlerExecute:此事件在执行HTTP处理程序之后发生。ReleaseRequestState:将会话状态重新存储在状态存储中。如果您要构建一个自定义会话状态模块,则必须将您的状态重新存储在状态存储中。
UpdateRequestCache:此事件将输出重新写入输出缓存。如果您要构建自定义缓存模块,则可以将输出重新写入缓存中。
EndRequest:请求已完成。您可能希望构建一个调试模块,以便将整个请求的信息收集到一起,然后将信息写入页面中。

DNN中的URLWriterHTTPModule详细介绍
URL重写是一个好的系统必须具备的。DNN的URL重写也是给大家提供了很多种URL重写的格式,归根到底也是为了URL的友好型,以及有利于SEO。下面这个就是DNN的一个友好的URL:http://www.dotnetnuke.com/RoadMap/FriendlyURLs/tabid/622/default.aspx如果你对URL的友好型不了解请直接Google下或者是请假下别人,这里不再罗嗦。
URL重写实在HTTPPipeline的请求进行时发生的,所以能够作为整个应用程序的事件。这里用到的HTTPModule事件是BeginRequest。也就是说每次一个页面向服务器发送HTTPHandler请求前通过BeginRequest事件让服务器相信你的url是接下来请求的那个页面的。
这种转换过程借助于SiteUrls.config文件中的正则表达式来完成。

<?xmlversion="1.0"encoding="utf-8"?>

<RewriterConfig>

<Rules>

<RewriterRule>

<LookFor>.*/TabId/(/d+)(.*)/Logoff.aspx</LookFor>

<SendTo>∼/Admin/Security/Logoff.aspx?tabid=$1</SendTo>

</RewriterRule>

<RewriterRule>

<LookFor>.*/TabId/(/d+)(.*)/rss.aspx</LookFor>

<SendTo>∼/rss.aspx?TabId=$1</SendTo>

</RewriterRule>

<RewriterRule>

<LookFor>[ˆ?]*/TabId/(/d+)(.*)</LookFor>

<SendTo>∼/Default.aspx?TabId=$1</SendTo>

</RewriterRule>

</Rules>

</RewriterConfig>



可以看到里面的节点主要是LookFor和SendTo。没错。也就是说当程序发现URL是…tabid/622/rss.aspx时它就会去找到rrs.aspx?Tabid=622来获取内容。后面的url是代码所能是别的url。
相同的道理如果url是http://localhost/dotnetnuke_community_cs/tabid/21/portalid/0/Default.aspx那么实际上的url是default.aspx?tabid=21。
当然你如果喜欢你可以强制性的去把某个url绝对比配,不使用正则表达式。


<RewriterRule>

<LookFor>.*/XXOO/Url.aspx</LookFor>

<SendTo>∼/default.aspx?tabid=622</SendTo>

</RewriterRule>





接下来我们分析下上面给出的基本的DNNurl:http://www.dotnetnuke.com/RoadMap/FriendlyURLs/tabid/622/default.aspxhttp://www.dotnetnuke.com---是整个网站的url
RoadMap/FriendlyURLS---是导航菜单的名字。也就是1级菜单的名字。你可以到DNN官网上试试。
Tabid/622/---是真实的url中的参数(?tabid=622)
Default.aspx---DNN中最重要那个页面吧。。。

当然了那个导航菜单是否需要显示在url中你可以通过web.config文件中friendlyurl部分来设定。可能对于一个小的网站你在主网站下不需要再分类了,比如不需要分什么product,community等。



DNN这种URL重写的方式最大的优点不需要从服务器查找数据来进行url的重写准备,而是使用正则表达式。我见过很多网站的URL重写时需要不停地和数据库交互,对于大的网站这个很影响性能的。

上面这个URL格式是对于SEO有好处的,但是很多时候大家希望有一个容易记住的url也就是传说中的人性化。但是这个只适合小型网站,你就硬写入上面那个配置文件中。DNN5也有一个配置能够让URL成为人类友好型的那种。这里不说了。
DNN的URL重写也使用了ProviderModule模式,别于大家去扩展它的URL重写。不得不佩服它的扩展性,无处不在啊。。。



上面既然说它扩展性好,如何去写一个自己的URL重写provider呢?
首先你需要创建一个Provider类是继承下面这个类的:



然后你在这些方法里面写入自己公司的url从写规则。具体的我会在后面文章里给出例子。写完这个编译后,你只需要在web.config中把你的provider加进来就可以了。





代码

<friendlyUrldefaultProvider="CustomFriendlyUrl">

<providers>

<clear/>

<addname="DNNFriendlyUrl"

type="DotNetNuke.Services.Url.FriendlyUrl.DNNFriendlyUrlProvider,

DotNetNuke.HttpModules.UrlRewrite"includePageName="true"

regexMatch="[ˆa-zA-Z0-9_-]"/>

<addname="CustomFriendlyUrl"

type="CompanyName.FriendlyUrlProvider,CompanyName.FriendlyUrlProvider"/>

</providers>

</friendlyUrl>





上面只是粗略的说明了下DNN的url重写是如何进行的。代码级别的研究以及自定义url规则都会单独有文章来介绍。
PS:DNN的URL重写你如果掌握了,你完全可以把它移植出来到你的项目中。

DNN的ExceptionHTTPModule模块
上面url重写部分使用的是BeginRequest事件,而Exception模块我们需要在整个应用程序发生错误时就去执行某个方法。代码如下:


也同时会把这个异常信息存储到数据库中来供开发人员分析。


DNN的UserOnlineHTTPModule

这个Module监听的是AuthorizeRequest事件。每当一个用户向服务器端发出身份认证时这个HTTPModule就会向服务器发送请求,useronlineprovider就会执行。




DNN的usernolineprovider主要是使用Cookie来存放唯一标识的。这样可以防止那些在线的游客被重复记录。当然了这个功能主要是靠DNN的Scheduler模块在后台有个线程没几分钟去执行下。DNNUserOnline模块的代码级别研究也会在以后一篇文章里介绍。这里你知道原理就行。

其它还有Membership,Compression,RequestFilter,Analytics,Compression模块。Analytics这个功能我觉得对于很多监测网站数据访问量的人员来说是个很好的参考。我会把对它的说明和Requestfilter放在一块讲解。估计接下来HttpModule部分还得写7-8篇文章才行。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: