深入了解ASP.NET运行内幕

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了深入了解ASP.NET运行内幕相关的知识,希望对你有一定的参考价值。

参考技术A

  事情要知道根本所在 原理所在 写程序更应该知道程序的运行机制 本文主要介绍 的运行内幕

  HttpApplication触发事件来通知你的程序有事发生 以此来负责请求流转 这作为HttpApplication Init()函数的一部分发生(用Reflector查看System Web HttpApplication InitInternal()方法和HttpApplication ResumeSteps()方法来了解更多详情) 连续设置并启动一系列事件 包括执行所有的处理器(handler) 这些事件处理器映射到global asax中自动生成的哪些事件中 同时它们也映射到所有附加的HttpModule(它们本质上是HttpApplication对外发布的额外的事件接收器(sink))

  HttpModule和HttpHandler两者都是根据nfig中对应的配置被动态载入并附加到事件处理链中 HttpModule实际上是事件处理器 附加到特殊的HttpApplication事件上 然而HttpHandler是用来处理 应用级请求处理 的终点

  HttpModule和HttpHandler两者都是在HttpApplication Init()函数调用的一部分中被载入并附加到调用链上 图 显示了不同的事件 它们是何时发生的以及它们影响管道的哪一部分

  图 事件在ASP NET 管道中流转的过程 HttpApplication对象的事件驱动请求在管道中流转 Http Module可以拦截这些事件并覆盖或者扩展现有的功能

  HttpContext HttpModules 和 HttpHandlers

  Application它本身对发送给应用程序的数据一无所知 它只是一个通过事件来通讯的消息对象 它触发事件并通过HttpContext对象来向被调用函数传递消息 实际的当前请求的状态数据由前面提到的HttpContext对象维护 它提供了所有请求专有的数据并从进入管道开始到结束一直跟随请求 图 显示了ASP NET管道中的流程 注意上下文对象(即HttpContext) 这个从请求开始到结束一直都是你 朋友 的对象 可以在一个事件处理函数中保存信息并在以后的事件处理函数中取出

  一旦管道被启动 HttpApplication开始象图六那样一个个的触发事件 每个事件处理器被触发 如果事件被挂接 这些处理器将执行它们自己的任务 这个处理的主要任务是最终调用挂接到此特定请求的HttpHandler 处理器(handler)是ASP NET请求的核心处理机制 通常也是所有应用程序级别的代码被执行的地方 记住ASP NET页面和Web服务框架都是作为HttpHandler实现 这里也是处理请求的的核心之处 模块(module)趋向于成为一个传递给处理器(handler)的上下文的预处理或后处理器 ASP NET中典型的默认处理器包括预处理的认证 缓存以及后处理中各种不同的编码机制

  有很多关于HttpHandler和HttpModule的可用信息 所以为了保持这篇文章在一个合理的长度 我将提供一个关于处理器的概要介绍

  HttpModule

  当请求在管道中传递时 HttpApplicaion对象中一系列的事件被触发 我们已经看到这些事件在Global asax中作为事件被发布 这种方法是特定于应用程序的 可能并不总是你想要的 如果你要建立一个通用的可用 *** 入任何Web应用程序的HttpApplication事件钩子 你可用使用HttpModule 这是可复用的 不需要特定语应用程序代码的 只需要nfig中的一个条目

  模块本质上是过滤器(fliter) 功能上类似于ISAPI过滤器 但是它工作在ASP NET请求级别上 模块允许为每个通过HttpApplication对象的请求挂接事件 这些模块作为外部程序集中的类存贮 在nfig文件中被配置 在应用程序启动时被载入 通过实现特定的接口和方法 模块被挂接到HttpApplication事件链上 多个HttpModule可用被挂接在相同的事件上 事件处理的顺序取决于它们在nfig中声明的顺序 下面是在nfig中处理器定义

  <configuration>

  <system web>

  <Modules>

  <add name= BasicAuthModule

  type= HttpHandlers BasicAuth WebStore />

  </Modules>

  </system web>

  </configuration>

  注意你需要指定完整的类型名和不带dll扩展名的程序集名

  模块允许你查看每个收到的Web请求并基于被触发的事件执行一个动作 模块在修改请求和响应数据方面做的非常优秀 可用为特定的程序提供自定义认证或者为发生在ASP NET中的每个请求增加其他预处理/后处理功能 许多ASP NET的功能 像认证和会话(Session)引擎都是作为HttpModule来实现的

  虽然HttpModule看上去很像ISAPI过滤器 它们都检查每个通过ASP NET应用的请求 但是它们只检查映射到单个特定的ASP NET应用或虚拟目录的请求 也就是只能检查映射到ASP NET的请求 这样你可以检查所有ASPX页面或者其他任何映射到ASP NET的扩展名 你不能检查标准的 HTM或者图片文件 除非你显式的映射这些扩展名到ASP NET ISAPI dll上 就像图 中展示的那样 一个常见的此类应用可能是使用模块来过滤特定目录中的JPG图像内容并在最上层通过GDI+来绘制 样品 字样

  实现一个HTTP模块是非常简单的:你必须实现之包含两个函数(Init()和Dispose())的IHttpModule接口 传进来的事件参数中包含指向HTTPApplication对象的引用 这给了你访问HttpContext对象的能力 在这些方法上你可以挂接到HttpApplication事件上 例如 如果你想挂接AuthenticateRequest事件到一个模块上 你只需像列表 中展示的那样做

  列表 :基础的HTTP模块是非常容易实现的

  public class BasicAuthCustomModule : IHttpModule

  

  public void Init(HttpApplication application)

  

  // *** Hook up any HttpApplication events

  application AuthenticateRequest +=

  new EventHandler(this OnAuthenticateRequest);

  

  public void Dispose()

  public void OnAuthenticateRequest(object source EventArgs eventArgs)

  

  HttpApplication app = (HttpApplication) source;

  HttpContext Context = HttpContext Current;

  … do what you have to do…                       

  

  记住你的模块访问了HttpContext对象 从这里可以访问到其他ASP NET管道中固有的对象 如请求(Request)和响应(Response) 这样你还可以接收用户输入的信息等等 但是记住有些东西可能是不能访问的 它们只有在处理链的后段才能被访问

  你可以在Init()方法中挂接多个事件 这样你可以在一个模块中实现多个不同的功能 然而 将不同的逻辑分到单独的类中可能会更清楚的将模块进行模块化(译注:这里的模块化和前面的模块没有什么关系)在很多情况下你实现的功能可能需要你挂接多个事件 例如一个日志过滤器可能在BeginRequest事件中记录请求开始时间 然后在EndRequest事件中将请求结束写入到日志中

  注意一个HttoModule和HttpApplication事件中的重点:Response End()或HttpApplication CompleteRequest()会在HttpApplication和Module的事件链中 抄近道 看 注意Response End() 来获得更多信息

  注意Response End()

lishixinzhi/Article/program/net/201311/11658

ASP.NET Core 技术内幕与项目实战读后感

前几天拿到了杨中科老师的新书《ASP.NET Core 技术内幕与项目实战》,迫不及待的“两”口气读完了。用一句话来总结,这是一本写给.NET开发者的非常实用接地气的好书,感觉有必要自发为这本书宣传一波。

杨老师在 .NET 开发者社区中的知名度非常高,很多年前就发布了一系列的 .NET 学习教程,造福了众多开发者。我自己也写blog,深知要把技术讲的通俗易懂是非常有难度的。而杨中科老师的视频在社区中非常流行,全网几十万粉丝,也算技术社区的网红了,证明杨老师在技术培训领域的深入功底。去年我提名了杨老师申请微软MVP奖项,很顺利就通过了,这也是微软对杨老师多年来对技术社区贡献的一种肯定,其实这个奖项早就应该给了。

得知杨老师在写书之后,一直期待这本书的问世。没想到这本书竟然花了三年时间,但算上作者已经近18年的开发经验,可谓“十年磨一剑”。这本书结合了作者多年来的软件开发实战经验,非常适合已经入门的 .NET 开发者作为进阶提高的必读书目。接下来谈一下我对本书的看法。

语言通俗生动,不枯燥。

技术书往往容易陷入繁杂的理论细节而让读者感到枯燥。特别是涉及到某个细节或者原理的时候,用一些特别高大上的名词会非常拗口。而这本书的用词非常通俗易懂,而且贴合生活实际。如本书讲解 DDD 应用,书中讲到:

DDD并不是一个技术,而是一种架构设计的指导原则。……DDD就像烹饪中餐时“盐少许、油少许”一样让人难以捉摸。……不同的人对DDD的理解及对DDD概念落地的理解有所不同,并不存在绝对的错与对,在情况A下成功的DDD实战经验放到情况B下可能就会失败。正如古人所说“橘生淮南则为橘,生于淮北则为枳”,读者不要在众多的对DDD解读的文章中迷失,也不要执着于寻找根本就不存在的“DDD最佳实践”,而要认证聆听各方的解读,并且根据项目的自身情况来个性化地实现DDD的落地。

这种形象化的比喻在书中比比皆是,非常容易让读者理解作者想要传达的意图。我想可能是因为杨老师已经出版了多本技术类的书籍,想来写作已经是驾轻就熟了。

深入原理——How 和 Why

技术书籍的写作,有一点是不要照抄文档。因为官方文档对各个 API 怎么使用已经有了详细的讲解。那为什么还需要书呢?因为文档只是告诉开发者这个技术怎么用,往往很少去解释为什么。而这本书解释了很多技术背后的原理,适用哪些场景,以及各自的优缺点,有哪些需要注意的问题。比如 IQueryable 这个接口,我们都知道 IQueryableIEnumberable 是不同的,那底层的具体实现有何区别?在书中详细解释了 IQueryable 是如何调用 DateReader这个底层方法来进行查询的,并通过几段代码演示了底层查询的过程,还讲解了在哪些场景下应该使用 IQueryable。这种层次的剖析不但可以让读者知道怎么使用它,还可以更加深入的了解为什么要这么做。

由浅入深,循序渐进

很多技术的发明或应用,并不是突然出现的,而是为了解决某个问题。比如说到缓存,我们都知道缓存可以提高性能,缓存又有不同的类型,比如客户端缓存和服务端缓存。那具体到不同的缓存类型,是为了解决什么问题呢?本书详细解释了问题的场景,并一步步引导读者去理解为什么要使用缓存。从HTTP支持的客户端缓存开始,然后到服务器端的响应缓存,而服务器端的缓存由单机的内存缓存开始,逐步去解决分布式缓存的问题。然后又遇到缓存穿透和缓存雪崩等问题,最后还提供了一个封装分布式缓存操作的实际案例,这一步步的问题+解决方案的方式,让读者跟随作者思路对如何应用缓存有了更深入的理解,从而可以应用到自己实际的项目中。

贴合实际,不拘泥于教条

本书我感觉最大的一个特点,就是非常接地气。理论是必须的,但理论不是教条,而应该根据实际情况灵活应对。在读到本书中关于 RESTful 的章节时,我感觉书中描述的实践其实并不是非常符合 RESTful 的定义,特别是在路由中使用动词的设计。但书中提到了:

REST 概念是用来指导我们设计接口的,而不是给开发带来麻烦的,不能因为要通过 RESTful 风格而影响开发进度及系统的稳定。……因此在进行项目开发的时候,需要根据项目特点、公司人员等多方面情况,确定一个符合项目情况的定制版 RESTful 规范。……

这种思路我是非常支持的。国外提出的某些理论,并不一定是要严格遵守的规范。只要团队内部有统一的认识,能够支持项目的开发,就可以成为良好的实践。书中对错误处理的 “200 派” 和 “4xx 派”也进行了相当精彩的描述,可以说这些内容都是来源于作者丰富的一线经验,而不是仅仅局限在某些理论中。

引纲挈领,以实际项目支撑

书中讲述了很多作者多年来的实战经验,更难为可贵的是,这些经验不是停留在泛泛的文字之中,作者甚至开发了多个 NuGet 包,并概要介绍了实现的关键代码。这说明作者完全不是空口无凭的理论派,而是具有丰富经验的实战派。比如用于 EF 批量操作的包、管理分布式缓存的包、读取数据库配置的包等等,这些都是已经发布到 NuGet 的开源项目,完全经得起实际应用的考验。更令我佩服的是,最后的项目案例章节中,完整讲述了作者开发的英语学习网站的技术细节,这是一个真正在运行的项目,据我所知已经有很多用户了。这种案例,当然比简单的图书管理系统或订单管理系统更有说服力。

其他

我也在写一本关于 ASP.NET 的书,但我感觉很难比杨老师写的更好。这本书也给我指明了方向,就是如何写一本让读者读得进、读得懂、读完大有收获的书。特别是本书关于 DDD 的章节,写的非常通俗易懂,我读了之后也感觉颇有收获。如果硬要说本书的不足,我感觉可能是因为本书重点关注开发的原因,对程序部署、监控、日志等内容涉及不多,比如如何容器化、如何实现 CI/CD、如何利用云原生平台等,其实严格说这些属于 DevOps 的范畴,值得写另一本书了。这可以算我鸡蛋里挑骨头吧。8-)

广告

最后再打个硬广,如果您对杨老师的书感兴趣,或者想与杨老师直接交流,或者只想听听什么是 DDD,那么机会来了,7月28日晚7点(新西兰时间)我们CITA NZ(新西兰华人 IT 协会)将邀请杨中科老师做一期讲座,名为“接地气的 DDD (领域驱动设计)实战指南”,线上活动,欢迎大家参加。在本公众号回复 DDD 即可获取报名链接。

这本书已经在各大电商上架,推荐 .NET 开发者快快下单吧!点击下方京东链接可直接下单。纯自发广告,杨老师请尽快付我广告费“少许”,谢谢。

👇👇👇

以上是关于深入了解ASP.NET运行内幕的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET Core 技术内幕与项目实战读后感

深入研究 Mini ASP.NET Core(迷你 ASP.NET Core),看看 ASP.NET Core 内部到底是如何运行的

asp.net EF学习系列----深入理解查询延迟加载技术

七天学会ASP.NET MVC ——深入理解ASP.NET MVC

4.4管道Middleware简介「深入浅出ASP.NET Core系列」

NET/ASP.NET Routing路由(深入解析路由系统架构原理)(转载)