ASP.NET HTTP运行时组成详解(下)

 我来答
一袭可爱风1718
2022-10-10 · TA获得超过1.2万个赞
知道大有可为答主
回答量:6617
采纳率:99%
帮助的人:37.7万
展开全部

   三 HTTP 管道

  ASP NET ISAPI 扩展启动辅助进程后 它将传递部分命令行参数 辅助进程使用这些参数来执行加载 CLR 前需要执行的任务 传递的值包括 和 D 安全性所要求的身份验证等级 可以使用的命名管道的数量和 IIS 进程标识 命名管道的名称是使用 IIS 进程标识和允许的管道数随机生成的 辅助进程不接收可用管道的名称 但可以接收识别管道名称所需的信息

   和 D 安全性与 Microsoft? NET Framework 有何关系?实际上 CLR 是作为 对象提供的 更准确地说 CLR 本身不是由 代码构成的 但是指向 CLR 的接口却是一个 对象 因此 辅助进程加载 CLR 的方式与加载 对象的方式相同

  当 ASPX 请求遇到 IIS 时 Web 服务器将根据选择的身份验证模型(匿名 Windows Basic 或 Digest)来分配一个令牌 当辅助进程收到要处理的请求时 令牌被传递到辅助进程 请求由辅助进程中的线程获取 该线程从最初获取传入请求的 IIS 线程继承身份令牌 在 aspnet_wp exe 中 负责处理请求的实际帐户取决于在特殊的 ASP NET 应用程序中是如何配置模拟的 如果模拟被禁用(默认设置) 则线程将在辅助进程的帐户下运行 默认情况下 该帐户在 ASP NET 进程模型中为 ASPNET 在 IIS 进程模型中为 NEORKSERVICE 这两个帐户都是 弱 帐户 提供的功能比较有限 可以有效抵挡回复性攻击 (Revert to self Attack) (回复性攻击是指将模拟的客户端的安全性令牌回复到父进程令牌 为辅助进程分配弱帐户可以挫败此类攻击 )

  高度概括起来 ASP NET 辅助进程完成的一项主要任务就是将请求交给一系列称为的 HTTP 管道的托管对象 要激活 HTTP 管道 可以创建一个 HttpRuntime 类的新实例 然后调用其 ProcessRequest 方法 如前所述 ASP NET 中始终只运行一个辅助进程(除非启用了 Web Garden 模型) 该进程在独立的 AppDomain 中管理所有的 Web 应用程序 每个 AppDomain 都有自己的 HttpRuntime 类实例 即管道中的输入点 HttpRuntime 对象初始化一系列有助于实现请求的内部对象 Helper 对象包括缓存管理器(Cache 对象)和内部文件系统监视器(用于检测构成应用程序的源文件的更改) HttpRuntime 为请求创建上下文 并用与请求相关的 HTTP 信息填充上下文 上下文用 HttpContext 类的实例来表示

  另一个在 HTTP 运行时的设置初期创建的 Helper 对象是文本书写器 用于包含浏览器的响应文本 文本书写器是 HttpWriter 类的实例 此对象对页面代码以编程方式发送的文本进行缓存 HTTP 运行时被初始化后 它将查找实现请求的应用程序对象 应用程序对象是 HttpApplication 类的实例 该类就是 global asax 文件背后的类 global asax 在编程时是可选的 但在构建结构时是必需的 因此 如果应用程序中没有构建类 则必须使用默认对象 ASP NET 运行时包括几个中间工厂类 可以用来查找并返回有效的 Handler 对象以处理请求 整个过程中用到的第一个工厂类是 HttpApplicationFactory 它的主要任务是使用 URL 信息来查找 URL 虚拟目录和汇集的 HttpApplication 对象之间的匹配关系

  应用程序工厂类的行为可以概括为以下几点

  工厂类维护 HttpApplication 对象池 并使用它们来处理应用程序的请求 池的寿命与应用程序的寿命相同

  应用程序的第一个请求到达时 工厂类提取有关应用程序类型的信息(global asax 类) 设置用于监视更改的文件 创建应用程序状态并触发 Application_OnStart 事件

  工厂类从池中获取一个 HttpApplication 实例 并将要处理的请求放入实例中 如果没有可用的对象 则创建一个新的 HttpApplication 对象 要创建 HttpApplication 对象 需要先完成 global asax 应用程序文件的编译

  HttpApplication 开始处理请求 并且只能在完成这个请求后才能处理新的请求 如果收到来自同一资源的新请求 则由池中的其他对象来处理

  应用程序对象允许所有注册的 HTTP 模块对请求进行预处理 并找出最适合处理请求的处理程序类型 这通过查找请求的 URL 的扩展和配置文件中的信息来完成

  HTTP 处理程序是一些实现 IHttpHandler 接口的类 NET Framework 为常见的资源类型提供了一些预定义的处理程序 包括 ASPX 页面和 Web 服务 machine config 文件中的 <Handlers> 部分定义了 HttpApplication 对象必须实例化才能处理特定类型资源的请求的类名 如果 Helper 类是一个处理程序工厂 GetHandler 方法将确定要使用的处理程序类型 这时 将从一组类似的对象中获取适当类型的处理程序 并对其进行配置以处理请求

  IHttpHandler 接口提供了两个方法 IsReusable 和 ProcessRequest 前者将返回一个布尔值 表示处理程序是否可以被汇集 (大多数预定义的处理程序都是汇集的 但是您可以自行定义每次都需要新实例的处理程序 )ProcessRequest 方法包含处理特定类型资源所需的所有逻辑 例如 ASPX 页面的处理程序基于以下伪代码

private void ProcessRequest() {// 确定请求是否是回发 (postback)IsPostBack = DeterminePostBackMode();

// 触发 ASPX 源代码的 Page_Init 事件PageInit();

// 加载 ViewState 处理已发送的值 if (IsPostBack) {LoadPageViewState();ProcessPostData();}

// 触发 ASPX 源代码的 Page_Load 事件PageLoad();

// ) 再次处理已发送的值(当// 动态创建控件时)// ) 将属性更改的服务器端事件提升为输入驱动的// 控件(即复选框的状态改变)// ) 执行与回发事件相关的所有代码if (IsPostBack) {ProcessPostDataSecondTry();RaiseChangedEvents();RaisePostBackEvent();}

// 触发 ASPX 源代码的 Page_PreRender 事件PreRender();

// 将控件的当前状态保存到 ViewState 中SavePageViewState();

// 将页面内容呈现给 HTMLRenderControl(CreateHtmlTextWriter(Response Output));}

  无论调用的资源类型如何 基于 HTTP 处理程序的模型是相同的 唯一随资源类型变化而变化的元素是处理程序 HttpApplication 对象负责查找应该使用哪种处理程序来处理请求 HttpApplication 对象还负责检测对动态创建的 表示资源的程序集(如 aspx 页面或 a *** x Web 服务)所进行的更改 如果检测到更改 应用程序对象将确保编译并加载所请求的资源的最新来源

   四 临时文件和页面程序集

  要全面了解 ASP NET HTTP 运行时 让我们来分析一下当请求 ASP NET 页面时 文件系统层所发生的变化 接下来 您将了解由 HTTP 管道的对象管理和监视的一组动态创建的临时文件

  虽然可以将页面的核心代码隔离在代码背后的 C# 或 Microsoft? Visual Basic? NET 类中 但可以将 Web 页面编写和部署为 aspx 文本文件 对于要显示为 URL 的页面来说 aspx 文件在应用程序的 Web 空间中必须始终可用 aspx 文件的实际内容将确定应用程序对象要加载的程序集(或多个程序集)

  按照设计 HttpApplication 对象将查找一个根据请求的 ASPX 文件命名的类 如果页面命名为 sample aspx 则要加载的相应的类名为 ASP sample_aspx 应用程序对象在 Web 应用程序的所有程序集文件夹中查找这样的类 这些文件夹包括全局程序集缓存 (GAC) Bin 子文件夹和 Temporary ASP NET Files 文件夹 如果未找到这样的类 HTTP 结构将分析 aspx 文件的源代码 创建一个 C# 或 Visual Basic NET 类(具体创建哪种类 取决于 aspx 页面上设置的语言) 同时对其进行编译 新创建的程序集的名称是随机生成的 位于特定于应用程序的子文件夹中 路径如下所示 C:\WINDOWS\Microsoft NET\Framework\v \Temporary ASP NET Files

  子文件夹 v 特定于 ASP NET 如果您使用的是 ASP NET 子文件夹的版本号会有所不同 即子文件夹名为 v 再次访问页面时 程序集就已存在 不需要重新创建 但是 HttpApplication 对象是如何确定特定于页面的程序集是否存在呢?它每次都要扫描大量文件夹吗?不 并不是这样

  应用程序对象只查看 Temporary ASP NET Files 文件夹中某个特殊文件夹的内容 具体路径(特定于应用程序的路径)由 HttpRuntime CodegenDir 属性返回 如果是第一次访问 aspx 文件(即还未创建页面程序集) 则该文件夹中就不存在以 ASPX 页面名称开头的 XML 文件 例如 具有动态程序集的 sample aspx 页面应有如下的条目

  sample aspx XXXXX xml

  XXXXX 占位符是一种散列代码 通过读取该 XML 文件的内容 应用程序对象就可以了解要加载的程序集的名称以及要在其中获取的类 以下代码片段是这种 Helper 文件的典型内容 包含 ASP sample_aspx 类的程序集的名称是 mvxvx xr

<preserve assem= mvxvx xr type= ASP sample_aspx ><filedep name= c:\inetpub\root\vdir\sample aspx /></preserve>

  当然 只有在分析 filedep 文件的源代码以生成动态程序集时才创建该文件 对 filedep 文件所做的任何更改都会使程序集无效 在下一次请求时必须重新编译 需要注意的是 在 ASP NET 架构的未来版本中 该实现过程可能会有较大改变 不论什么原因 只要您决定在当前应用程序中使用它 都必须十分小心

  由于更新而要为页面创建新的程序集时 ASP NET 将验证是否可以删除旧的程序集 如果旧的程序集只包含修改后的页面的类 ASP NET 将试图删除并替换该程序集 否则将在保留旧程序集的情况下创建一个新程序集

  在删除过程中 ASP NET 可能会发现程序集文件已被加载并锁定 这种情况下 可以为旧程序集添加一个 DELETE 扩展名 以将其重新命名 (注意 所有 Windows 文件都可以在使用过程中重新命名 )只要应用程序重新启动(例如 由于对某个应用程序文件如 global asax 和 web config 进行了更改) 这些临时的 DELETE 文件就将被删除 但在处理下一个请求时 ASP NET 运行时不会删除这些文件

  请注意 默认情况下 在整个应用程序重新启动之前 每个 ASP NET 应用程序最多可以重新编译 个页面 同时会损失一些会话和应用程序数据 当最近的编译次数超过了 <Runtime> 部分的 numRepilesBeforeAppRestart 属性中设置的阈值时 将卸载 AppDomain 并重新启动应用程序 还要注意 在 NET Framework 中 您无法卸载单个程序集 AppDomain 是可以从 CLR 卸载的最小的代码块

   五 小结

  ASP NET 应用程序有两大特征 进程模型和页面对象模型 ASP NET 提前使用了 IIS 的一些功能 而 IIS 则是 Windows Server 中提供的全新的 开创性的 Microsoft Web 信息服务 尤其值得一提的是 在独立的辅助进程中运行的 ASP NET 应用程序 其行为与 IIS 中的所有应用程序相同 而且 尽管会出现运行时异常 内存泄露或程序错误 ASP NET 运行时仍能自动回收辅助进程以保证实现卓越的性能 这种功能已成为 IIS 的系统功能

lishixinzhi/Article/program/net/201311/15766

已赞过 已踩过<
你对这个回答的评价是?
评论 收起
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式