文章引导

1.ASP.NET的底层体系1

2.ASP.NET的底层体系2

引言:

学习ASP.NET,要想做的更好,不了解ASP.NET是不行的。一个有理想的程序员都会像挤压海绵一样,努力的去学习和获取宝贵的知识。

本篇文档内容,转自小皓园的博文--->(翻译)从底层了解ASP.NET体系结构,以此来尊重原创精神,并对其进行提炼,去掉一些无关的内容。

一.ASP.NET是什么

ASP.NET是一个请求处理引擎,它获取客户端的请求,然后通过内置的管道,把请求传递到终点,在这个终点,开发者可以添加处理这个请求的逻辑代码。

整个ASP.NET引擎构建在托管代码里,所有的扩展功能都是通过托管代码的扩展提供。

使用ASP.NET可以完成一些任务,之前这些任务是使用IIS的ISAPI扩展和过滤来完成的,尽管还有一些限制,但与ASP相比,已经有了很大的进步。ISAPI是底层Win32样式的API,它的接口就有1M,这样对于大型程序开发是非常困难的,由于ISAPI是底层的接口,因此它的速度也是很快的。

微软的ASP.NET和IIS的接口是通过宿主在.NET里的ISAPI扩展来通信的,ISAPI提供了与WebServer通信的核心接口,然后ASP.NET使用非托管代码获取请求发出响应。

二.HTTP

HTTP运行时提供了一套复杂的机制,在处理请求的每一个层面都牵涉许多对象,但大多数对象都可以通过派生或事件接口来扩展。通过HTTP,可以进入较低层次的接口如:缓存、身份验证、授权等信息。可以在处理请求之前或之后过滤内容等等。

三.从浏览器到ASP.NET

我们从一个典型的ASP.NET Web请求的生命周期开始说起。用户通过在浏览器输入一个URL,点击链接,提交一个HTML表单(一个POST请求),或者一个客户端程序调用基于ASP.NET的Web Services。在服务端,IIS收到这个请求。

ASP.NET的底层通过ISAPI扩展与IIS通信,然后,通过ASP.NET这个请求通常被路由到一个带.aspx扩展名的页面,但是这个处理过程如何工作,则完全依赖于HTTP处理器(handler)的执行。在IIS中,.aspx经由“应用程序扩展”被映射到ASP.NET ISAPI的dll文件:aspnet_isapi.dll,每一个触发ASP.NET的请求,都必须由一个已经注册的,并且指向aspnet_isapi.dll的扩展名来标识。

依靠扩展名,ASP.NET把一个请求路由到一个恰当的处理器,该处理器则负责处理这个请求。

例子:Web Service的扩展名.asmx不会把一个请求路由到磁盘的某一个页面,而是会路由到定义中附加了指定特性的类,此特性会把它标记为一个Web Services的实现。

四.ISAPI

ISAPI是底层非托管的Win32 API,它定义的接口非常的单一且性能最优。用这些接口处理原始指针(raw pointer),而函数指针列表(function pointer)则用于回调。ISAPI提供了最底层的、高性能的接口。

ISAPI趋向于被当做桥接口使用,用于给高层级的工具提供应用服务类型的功能。

例子:ASP.NET就是构建在ISAPI之上,ISAPI给高层次的应用程序提供了高性能垂直访问接口,使得高层次的应用程序需要的信息可以从ISAPI提供的信息中提炼,引擎可以提炼ISAPI接口提供的表单里的对象有:Request Response。

作为约定,ISAPI支持ISAPI扩展(extensions)和ISAPI过滤(filters),扩展是请求处理接口,提供了跟Web Server输入和输出相关的逻辑处理。从本质来说,它是一个事务接口。

ISAPI是钩子接口,它允许你查看进入IIS的每一个请求并可以修改请求的内容。

IIS把不同的扩展名如.aspx映射到ASP.NET的ISAPI扩展,通过这种机制,在WEB SERVER里,请求就可以被路由到ASP.NET的处理管道里。

五.IIS5   IIS6

当一个请求进来的时候,IIS会检查脚本映射,然后把请求路由到aspnet_isapi.dll。IIS 6总会保持一个单独的工作进程:应用程序池,所有的处理都发生在这个进程里。对于IIS 6来说,应用程序池是一个重大的改进,因为他们允许以更小的粒度控制一个指定进程的执行。你可以为每一个虚拟目录或者整个web站点配置应用程序池,这样它可以与运行在同一台机器的其他程序完全隔离。

应用程序池是高度可配置的,通过设置应用程序池的执行许可,可以配置他们的执行环境。对于ASP.NET而言,IIS 6最大的改进是使用应用程序池代替了machine.config里的ProcessModel实体的大部分功能。在IIS 5里,这个实体是很难管理的,因为它的设置是全局的,而且不能够在指定WEB程序的wen.config里覆盖这些设置。当IIS 6运行的时候,ProcessModel里的大部分配置将被忽略,取而代之的是读取应用程序池的配置。另外一些配置,像线程池的大小和IO线程数目等仍然还是要通过这个节点的配置。

IIS 6应用程序池也包含了ASP.NET固有的东西,ASP.NET可以和新的底层API通信,这些API允许直接访问HTTP缓冲存储器的API,而HTTP缓冲存储器的API可以直接进入Web SERVER的缓冲存储器,卸载ASP.NET级别的缓存。

在IIS 6里,ISAPI扩展运行在应用程序池的工作进程里,而.NET运行时也在这个进程里,所以ISAPI扩展和.NET运行时通信是发生在进程内。

六.进入.NET运行时

进入.NET运行时真正登录点发生在一些没有正式文档的类和接口之间。工作进程w3wp.exe宿主在.NET运行里。ISAPI dll通过底层的COM调用一小撮非托管类型的接口,其实最终调用的是ISAPIRuntime派生类的实例。进入运行时的第一个登录点是未归档的ISAPIRuntime类,它通过COM把接口IISAPIRuntime暴露给调用者,这些COM接口是底层的IUnknown。基于这些接口,就意味着ISAPI到ASP.NET之间的调用属于内部调用。

IISAPIRuntime接口担当着来自ISAPI扩展的非托管代码和托管代码之间的桥梁

[return:MarshallAs(UnmanagerType.I4)]

int ProcessRequest(IntPtr ecb,[In,MarshallAs(UnmanagerType.I4)] int useProcessMode)

ecb参数是ISAPI扩展控制块,它作为非托管资源传递给ProcessRequest方法,此方法将获取ECB,然后作为基本的输入和输出接口,用于Request和Response对象。ISAPI ECB包含着所有底层的请求信息,这其中包括服务器变量、用于表单变量的输入流和写数据并把数据发送到客户端的输出流中。一个单独的ECB引用基本提供了一个ISAPI请求可以访问的所有功能。

ISAPI扩展以异步的方式处理请求,所以当ISAPI扩展调用了工作进程或者IIS的线程后,会立即返回,但会为当前的请求保留ECB,因此,ECB需要包含这样的机制,当请求结束的时候通知ISAPI,然后ISAPI扩展释放ECB资源。接着以异步的方式立即释放ISAPI的工作线程和卸载由ASP.NET托管的那个隔离的处理线程。

ASP.NET得到ECB引用后,会在内部使用它来获取当前请求的相关信息。如服务器变量。ECB将就存活直到这个请求结束或者IIS超时,在这之前,ASP.NET将会与ecb继续保持通信,当请求结束的时候,输出的内容会写进ISAPI的输出流中。然后ISAPI扩展会被通知请求已经结束,让它知道ECB可以被释放了,这个执行过程是非常高效的。

七.ProcessRequest

ISAPI是多线程的,因此请求可以以多线程的方式穿过AppDomainFactory.Create()返回的对象引用。

public int ProcessRequest(IntPtr ecb,int iWRType)
{
//ISAPIWorkerRequest从HttpWorkRequest继承,这里创建的是一个ISAPIWorkerRequest派生类的一个实例
HttpWorkerRequest request=ISAPIWorkerRequest.CreateWorkerRequest(ecb,iWRType);
//得到请求的物理路径
string str=request.GetAppPathTranslated();
//得到AppDomain的物理路径
string str2=HttpRuntime.AppDomainAppPathInternal; if( str2==null || str.Equals(".") || string.Compare(str,str2,true,CultureInfo.InvariantCulture)==)
{
HttpRuntime.ProcessRequest(request);
return ;
} //如果外部请求的AppDomain物理路径和原来的AppDomain的路径不同,说明ISAPI维持的AppDomain已经失效,所以需要把原来的城西关闭
HttpRuntime.ShutDownAppDomain("from "+str+str2);
return ;
}

上述代码ProcessRequest接收一个ISAPI ecb对象和一个服务器类型参数,这个线程是安全的,因此多个ISAPI线程可以同时安全的调用单个返回对象的实例。

System.Web.Hosting.ISAPIWorkerRequest继承抽象类HttpWorkerRequest,它的职责是创建一个抽象的输入和输出视图,为Web程序的输入提供服务。上面的代码中有一个方法CreateWorkerRequest,这个方法的第二个参数用于指定创建什么样的工作请求对象,即ISAPIWorkerRequest的派生类,这里有三个不同的版本:ISAPIWorkerRequestInProc,ISAPIWorkerRequestInProcForIIS6,ISAPIWorkerRequestOutOfProc。当这个请求到来时,这个ISAPIWorkerRequest将被创建,用于给Request和Response对象提供基础服务,而这两个对象将从数据的提供者WorkerRequest接收数据流。

抽象类HttpWworkerRequest围绕着底层的接口提供了高层的抽象,这样就不用考虑数据的来源,无论他是一个CGI Web Server,Web浏览器还是自定义的机制(用于把数据流入HTTP运行),ASP.NET都可以以同样的方式从中获取数据。

有关IIS的抽象主要集中在ISAPI ECB块,在我们的请求处理当中,ISAPIWorkerRequest依赖于ISAPI ECB块。

ISAPIWorkerRequest实现了一个高层次包装器方法,它调用了低层次的核心方法,而这些方法负责实际调用非托管API或者是“服务层的实现”,核心的方法在ISAPIWorkerRequest的派生类中得以实现,这样可以针对它宿主的环境提供特定的实现,为以后增加一个额外环境的实现类作为新的Web Server接口提供了便利。

说句实话,上面的内容讲了这么多,头都被绕晕了。讲来讲去总结就是以下几点:

1.用户在浏览器输入一个URL,提交一个HTML表单。服务端的IIS接收到请求,ASP.NET的底层ISAPI与IIS通信,路由到指定的页面。

2.ISAPI是底层非托管的win32 API,ASP.NET都是构建在ISAPI之上,它给高层次的应用程序提供了高性能垂直访问接口。

3.在ISAPI扩展里,当第一个请求命中一个ASP.NET的映射扩展时,工作线程就会引导.NET运行时启动。一旦运行时存在了,非托管代码就可以为指定的虚拟目录请求一个ISAPRuntime的实例,当然这个前提是这个实例还不存在,每个虚拟目录都会拥有一个AppDomain,ISAPIRuntime存在于AppDomain中,它引导一个单独的程序启动。

ASP.NET的底层体系1的更多相关文章

  1. ASP.NET的底层体系2

    文章引导 1.ASP.NET的底层体系1 2.ASP.NET的底层体系2 引言 接着上一篇ASP.NET的底层体系1我们继续往下走 一.System.Web.HttpRuntime.ProcessRe ...

  2. 窥探ASP.Net MVC底层原理 实现跨越Session的分布式TempData

    1.问题的引出 我相信大家在项目中都使用过TempData,TempData是一个字典集合,一般用于两个请求之间临时缓存数据或者页面之间传递消息.也都知道TempData是用Session来实现的,既 ...

  3. ASP.NET MVC底层原理与框架

    前言 鄙人有一毛病,喜欢钻研原理性的东西,感觉只知道怎么用还不太够,更想知道如何实现的以及为什么会这样. 暑假的时候做积分系统是第一次接触MVC,感觉MVC就是一个框架,分为Module ,view和 ...

  4. 【转】从底层了解ASP.NET体系结构

    从底层了解ASP.NET体系结构 原文:http://blog.csdn.net/zhoufoxcn/article/details/1890158 Java体系架构的书多如牛毛,比如SSH架构什么的 ...

  5. (翻译)从底层了解ASP.NET体系结构 [转]

    转自:http://www.cnblogs.com/rijing2004/archive/2007/09/14/howaspnetwork.html 前言 关于ASP.NET的底层的工作机制,最近园子 ...

  6. 【转】(翻译)从底层了解ASP.NET体系结构

    原文地址:http://www.cnblogs.com/rijing2004/archive/2007/09/14/howaspnetwork.html 前言关于ASP.NET的底层的工作机制,最近园 ...

  7. ASP.NET底层与各个组件的初步认识与理解 (转载)

    ASP.NET底层的初步认识与理解   最近在国外的网站乱走一通,发现一些比较好的文章,收集整理加于自己的理解,作为笔记形式记录下来,让以后自己有个回忆. ASP.NET是一个非常强大的构建Web应用 ...

  8. 从底层了解ASP.NET体系结构

    导读:  前言  关于ASP.NET的底层的工作机制,最近园子里讨论的甚是火热.相信很多人都看过Rick Strahl先生的一篇经典之作:A low-level Look at the ASP.NET ...

  9. 学习ASP.NET Core,你必须了解无处不在的“依赖注入”

    ASP.NET Core的核心是通过一个Server和若干注册的Middleware构成的管道,不论是管道自身的构建,还是Server和Middleware自身的实现,以及构建在这个管道的应用,都需要 ...

随机推荐

  1. layerui ios不适应问题

    .admin-main {-webkit-overflow-scrolling: touch; overflow: scroll; position: absolute; left: 0; top:  ...

  2. jq-demo-阻止冒泡,阻止默认行为

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  3. Q:简单实现URL只能页面跳转,禁止直接访问

    sessionStorage 用于临时保存同一窗口(或标签页)的数据,在关闭窗口或标签页之后将会删除这些数据,且不同标签页的session不能共享,通过此特性来控制某个页面只能通过上级页面同标签页跳转 ...

  4. leetcood学习笔记-204-计算质数

    题目描述: 第一次提交;(超时): class Solution: def countPrimes(self, n: int) -> int: count = 0 for i in range( ...

  5. luoguP3281 [SCOI2013]数数

    传送门 抄的llj的代码 还有点问题没弄懂,先码着 //Achen #include<algorithm> #include<iostream> #include<cst ...

  6. 暑假集训test-8-30

    这套题有毒,T1标程挂了,T2题面完全莫名其妙,T3没有告诉取模害我打了好久高精... A题. 统计每个数后面比它小的数的个数记作f把,操作一个数就是把它后面所有比它小的数和它的f清0,然后若是它到它 ...

  7. JS常见的报错类型

    解决错误前,首先要学会阅读报错信息 eg:Uncaught TypeError: ... is not a function Uncaught 表示没有被catch语句捕获到的错误 TypeError ...

  8. delphi基础篇之单元文件

    Delphi单元文件 unit MainFrm; {库单元文件头} interface        {接口部分由Interface开始implementation结束.声明引用的单元,常量,数据类型 ...

  9. AtCoder ABC 126F XOR Matching

    题目链接:https://atcoder.jp/contests/abc126/tasks/abc126_f 题目大意 给定两个整数 M 和 K ,用小于 2M 的的所有自然数,每个两个,用这些数排成 ...

  10. A1016 Phone Bills (25 分)

    A long-distance telephone company charges its customers by the following rules: Making a long-distan ...