网站建设不能持续消费,把自己做的网站上传到服务器,wordpress搭建小程序商城,拓客软件哪个好用ASP.NET MVC 是建立在 ASP.NET 平台上基于 MVC 模式的 Web 应用框架#xff0c;深刻理解 ASP.NET MVC 的前提是对 ASP.NET 管道式设计具有深刻的认识。由于 ASP.NET Web 应用大都寄宿于 IIS 上#xff0c;将两者结合起来了解在 IIS 和 ASP.NET 管道中是如何流动的。
IIS5.x与…ASP.NET MVC 是建立在 ASP.NET 平台上基于 MVC 模式的 Web 应用框架深刻理解 ASP.NET MVC 的前提是对 ASP.NET 管道式设计具有深刻的认识。由于 ASP.NET Web 应用大都寄宿于 IIS 上将两者结合起来了解在 IIS 和 ASP.NET 管道中是如何流动的。
IIS5.x与ASP.NET
IIS5.x 是如何处理基于 ASP.NET 资源如.aspx、.asmx...请求的呢
IIS5.x运行在进程 InetInfo.exe 中该进程寄存着一个名为 World Wide Web Publishing Service简称W3SVC的 Windows 服务。W3SVC 主要负责 HTTP 请求的监听、激活、管理工作进程、加载配置从 Metabase 中加载相关配置信息等。 IIS5.x与ASP.NET
当检测到某个 HTTP 请求时IIS 先根据扩展名判断请求的是静态资源还是动态资源。对于静态资源 IIS 会将文件内容直接响应给客户端对于动态资源则通过扩展名从 IIS 的脚本映射Script Map中找到相应的ISAPI 动态链接库Dynamic Link Library DLL。
ISAPIInternet Server Application Programming Interface是一套本地的NativeWin32 API是 IIS 和其他动态 Web 应用或平台之间的纽带。
ISAPI 定义在一个动态链接库DLL文件中 ASP.NET ISAPI 对应的 DLL 文件名称为 aspnet_isapi.dll位于 %windir%\Microsoft.NET\Framework\{version no}\中。
ISAPI 支持 ISAPI 扩展ISAPI Extension和 ISAPI 筛选ISAPI Filter前者是真正处理 HTTP 请求的接口后者则可以在 HTTP 请求真正被处理之前查看、修改、转发、拒绝请求比如 IIS 可利用 ISAPI 筛选进行请求的验证。
若请求的是一个基于 ASP.NET 的资源类型如.aspx、.asmx、.svc等aspnet_isapi.dll 会被加载ASP.NET ISAPI 随后会创建 ASP.NET 的工作进程若该进程尚未启动。对于 IIS5.x 来说该工作进程为 aspnet.exe。IIS 进程与工作进程之间通过命名管道Named Pipes进行通信。
在工作进程初始化过程中.NET 运行时CLR会被加载以构建一个托管的环境。对于某个 Web 应用的初次请求CLR 会被其创建一个应用程序域Application Domain。
在应用程序域中HTTP 运行时HTTP Runtime被加载并用以创建相应的应用。寄存于 IIS5.x 的所有Web应用都运行在同一个进程工作进程 aspnet_wp.exe的不同应用程序域中。
IIS6.0 与 ASP.NET
IIS5.x存在两个方面的不足
ISAPI动态链接库被加载到 InetInfo.exe 进程中它和工作进程之间是一种典型的跨进程通信方式尽管采用命名管道仍会带来性能瓶颈。
解决方案IIS6.0将ISAPI动态链接库直接加载到工作进程中
ASP.NET 应用运行在相同进程 aspnet_wp.exe 的不同程序域中基于应用程序域的隔离不能从根本上解决一个应用程序对另一个程序的影响需不同的Web应用运行在不同的进程中。
解决方案IIS6.0 加入了应用程序池 Application Pool 的机制为一个或多个 Web 应用创建一个应用程序池每个应用程序池对应一个独立的工作进程 w3wp.exe所以运行在不同应用程序池中的 Web 应用提供基于进程级别的隔离机制。
HTTP.SYS
IIS6.0 中最重要的一点是创建了一个名为 HTTP.SYS 的 HTTP 监听器HTTP.SYS 以驱动程序的形式运行在Windows 的内核模式 Kernal Mode下它是 Windows TCP/IP 网络子系统的一部分从结构上看它属于 TCP 之上的一个网络驱动程序。
严格地说HTTP.SYS 已经不属于 IIS 的范畴了所以 HTTP.SYS 的配置信息也没有保存在 IIS 的元数据库Metabase而是定义在注册表中。HTTP.SYS 的注册表项的路径为HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/HTTP。
HTTP.SYS能够带来如下好处
持续监听
由于 HTTP.SYS 是一个网路驱动程序始终处于运行状态所以对于用户会的 HTTP 请求能够及时作出反应。
稳定性
HTTP.SYS 运行在操作系统内核模式下并不执行任何用户代码其本身不会受到 Web应用、工作进程、IIS进程的影响。
内核模式下的数据缓存
如果某个资源被频繁请求HTTP.SYS 会把响应的内容进行缓存缓存的内容可直接响应后续的请求。由于这是基于内核模式的缓存不存在内核模式和用户模式的切换响应速度得到极大的改进。
IIS6.0结构
与 IIS5.x 不同W3SVC 在 IIS6.0 中从 InetInfo.exe 进程脱离出来对于 IIS6.0 来说InetInfo.exe基本上可以看做单纯的 IIS 管理进程运行在另一个进程 SvcHost.exe中。不过 W3SVC 的基本功能并没有发生变化只是在功能的实现上作出相应的改进。与 IIS5.x 一样元数据库 Metabase 依然存在于InetInfo.exe进程中。 IIS6.0与ASP.NET
IIS6.0处理HTTP请求的流程
当监听到HTTP请求时HTTP.SYS 将其分发给 W3SVCW3SVC 解析出请求的 URL ,并根据从 Metabase 获取的 URL 与 Web 应用之间的映射关系得到目标应用进而得到目标应用运行的应用程序池或工作进程。如果工作进程不存在或尚未创建或被回收它为请求创建新的工作进程。在工作进程的初始化过程中相应的 ISAPI 动态链接库被加载对于 ASP.NET 应用来说被加载的 ISAPI.dll 为 aspnet_isapi.dll。ASP.NET ISAPI 负责进行 CLR 的加载、应用程序域的创建和 Web 应用的初始化等操作。
IIS7.0与ASP.NET
IIS7.0在请求的监听和分发机制上进行了革新体现在引入Windows进程激活服务Windows Process Activation Service, WAS分流了原来IIS6.0中W3SVC承载的部分功能。
IIS6.0中的W3SVC主要承载着如下三个功能
HTTP请求接收接收HTTP.SYS监听到的HTTP请求配置管理从元数据Metabase中加载配置信息对相关组件进行配置进程管理创建、回收、监控工作进程
IIS7.0将后两组功能实现到了WAS中但接收HTTP请求的任务依然落在W3SVC上。WAS的引入为IIS7.0提供了对非HTTP协议的支持通过监听适配器接口 Listener Adapter Interface抽象出针对不同协议的监听器。具体来说或除了专门用于监听HTTP请求的HTTP.SYS之外WAS利用TCP监听器、命名管道监听器和MSMQ监听器提供基于TCP、命名管道、MSMQ传输协议的监听支持。
与此3种监听器相对应的是3种监听适配器它们提供监听器与WAS中的监听适配器接口之间的适配从这个意义上讲IIS7.0中的W3SVC相当于HTTP.SYS的监听适配器。这3种非HTTP监听器和监听适配器定义在程序集 SMSvcHost.exe 中。可在目录%windir%\Microsoft.NET\Framework\v3.0\Windows Communication Foundation\中找到。
从程序集所在的目录名称可以看出这3种监听器/监听适配器是为WCF设计的它们以Windows服务的形式进行工作。虽然定义在一个程序集中。但依然可通过服务工作管理器对其进行单独的启动、终止、配置。总的来说SMSvcHost.exe提供了4个重要的Windows Service。
NetTcpPortSharing 为WCF提供TCP端口共享即同一个监听端口被多个进程共享。NetTcpActivator 为WAS提供基于TCP的激活请求包含TCP监听器和对应的监听适配器。NetPipeActivator 为WAS提供基于命名管道的激活请求包含命名管道和对应的监听适配器。NetMsmqActivator 为WAS提供基于MSMQ的激活请求包含MSMQ监听器和对应的监听适配器。Windows Service
IIS7.0架构 IIS7.0与ASP.NET
无论是从W3SVC接收到的HTTP请求还是通过WCF提供的监听适配器接收到的针对其他传输协议的请求最终都胡被传递到WAS。如果相应的工作进程针对单个应用程序池尚未创建则WAS会创建工作进程。WAS在进行请求处理过程中通过内置的配置管理模块加载相关的配置信息并对相关的组件进行配置。
与IIS5.x和IIS6.0基于Metabase的配置信息存储不同的是IIS7.0大多将配置信息存放在XML形式的配置文件中基本的配置存放在 applicationHost.config 中。
API.NET 集成
从IIS5.x和IIS6.0中不难发现IIS与ASP.NET是两个独立的管道 Pipeline。在各自管辖范围内各自具有自己的一套机制对HTTP请求进行处理。两个管道通过ISAPI实现连通。IIS是第一道屏障当对HTTP请求进行必要的前期处理如身份认证等。IIS通过ISAPI将请求分发给ASP.NET管道。当ASP.NET在自身管道范围内完成对HTTP请求的处理时处理后的结果再返回到IISIIS对其进行后期处理如日志记录、压缩等。之后生成HTTP回复对请求予以响应。 IIS6.0与ASP.NET之间的桥接关系 基于IIS6.0和ASP.NET双管道设计
从另一个角度讲IIS运行在非托管的环境中而ASP.NET管道则是托管的所以说ISAPI是连接非托管环境和托管环境的纽带。IIS5.x和IIS6.0把两个管道进行隔离带来的局限的不足是
相同操作的重复执行
IIS和ASP.NET之间具有一些重复的操作如身份验证。
动态文件与静态文件处理的不一致
因为只有基于ASP.NET 动态文件的HTTP请求才能通过ASP.NET ISAPI进入ASP.NET管道对于静态文件的请求则由IIS直接响应那么ASP.NET管道中的一些功能将不能作用域这些基于静态文件的请求比如通过Forms认证应用于基于图片文件的请求就做不到。
IIS难以扩展
对于IIS的扩展基本上提现在自定义ISAPI对于大部分人来说这不是一件容易的事情因为ISAPI是基于Win32的非托管的API并非一种面向应用的编程接口。通常希望的是诸如定义ASP.NET的HttpModule和HttpHandler一样托管代理的方式来扩展IIS。
对于Windows平台下的IIS来讲ASP.NET无疑是一等公民IIS7.0中实现了两者的集成通过集成可获得如下好处
允许通过本地代码Native Code和托管代码Managed Code两种方式定义IIS Module
这些IIS Module注册到IIS中形成一个通用的请求处理管道由IIS Module组成的这个管道能够处理所有的请求无论请求基于怎样的资源类型。例如可将FormAuthenticationModule提供的Forms认证应用到基于 .aspx、CGI和静态文件的请求。
将ASP.NET提供的一些强大的功能应用到原来难以企及的地方
比如将ASP.NET的URL重写功能置于身份验证之前
采用相同的方式去实现、配置、检测和支持一些服务器特性 Feature
比如Module、Handler映射、定制错误配置 Custom Error Configuration 等 基于IIS7.0 与 ASP.NET集成管道设计
ASP.NET 管道
以 IIS6.0为例它的工作进程 w3wp.exe 中会利用 aspnet_isapi.dll 加载 .NET 运行时如果 .NET 运行时尚未加载。IIS6.0引入了应用程序池的概念一个工作进程对应着一个应用程序池。一个应用程序池可以承载一个或多个Web应用每个Web应用映射到一个IIS虚拟目录与IIS5.x一样每个Web应用运行在各自的应用程序域中。 ASP.NET 处理管道
如果HTTP.SYS接收到的HTTP请求是对该 Web 应用的第一次访问在成功加载运行使之后IIS会通过 AppDomainFactory 为该Web应用创建一个应用程序域。随后一个特殊的运行时 IsapiRuntime 被加载。IsapiRuntime 定义在程序集 System.Web.dll中对应的命名空间为System.Web.Hosting 被加载的 IsapiRuntime 会接管该HTTP请求。
接管 HTTP 请求的 IsapiRuntime 会首先创建一个 IsapiWorkerRequest 对象来封装当前的HTTP请求随后将次对象传递给 ASP.NET 运行时 HttpRuntime。从此时起 HTTP请求正式进入了ASP.NET管道。HttpRuntime会根据 IsapiWorkerRequest 对象创建用于表示当前HTTP请求的上下文 Context 对象 HttpContext。
随着 HttpContext 的创建HttpRuntime 会利用 HttpApplicationFactory 创建新的或获取现有的 HttpApplication 对象。实际上 ASP.NET 维护着一个 HttpApplication 对象池 HttpApplicationFactory 从池中选取可用的 HttpApplication 用于处理 HTTP 请求处理完毕后将其释放到对象池中。HttpApplication 负责处理当前的 HTTP 请求。
在 HttpApplication 初始化过程中ASP.NET 会根据配置文件加载并初始化注册的 HttpModule 对象。对于 HttpApplication 来说在它处理HTTP请求的不同阶段会触发不同的事件 Event而HttpModule的意义在于通过注册HttpApplication的相应事件将所需的操作注入整个HTTP请求的处理流程。ASP.NET的很多功能都是通过相应的HttpModule实现的。
最终完成对HTTP请求的处理实现在HttpHandler中不同的资源类型对应着不同类型的HttpHandler。比如.aspx页面对应的HttpHandler类型为System.Web.UI.PageWCF的.svc文件对应的HttpHandler类型为System.ServiceModel.Activation.HttpHandler。
HttpApplication
HttpApplication 是整个 ASP.NET 基础架构的核心负责处理分发给它的HTTP请求。由于一个HttpApplication对象在某个时刻只能处理一个请求只有完成对某个请求的处理后才能用于后续请求的处理所以ASP.NET采用对象池的机制来创建或获取 HttpApplication 对象。
当第一个请求抵达时ASP.NET会一次创建多个HttpApplication对象并将其置于池中然后选择其中一个对象来处理该请求。处理完毕后HttpApplication不会被回收而是释放到池中。对于后续的请求空闲的 HttpApplication 对象会从池中取出。如果池中所有的 HttpApplication 对象都处于繁忙的状态在没有超出 HttpApplication 池最大容量的情况下ASP.NET 会创建新的HttpApplication对象否则将请求放入队列等待现有HttpApplication的释放。
HttpApplication 处理请求的整个生命周期是一个相对复杂的过程在该过程的不同阶段会触发相应的事件。可注册相应的事件将处理逻辑注入到HttpApplication处理请求的某个阶段。
HttpApplication在处理每个请求时触发的事件 BeginRequest HTTP管道开始处理请求时会触发BeginRequest事件。 AuthenticateRequest, PostAuthenticateRequest ASP.NET 先后触发这两个事件使安全模块对请求进行身份验证。 AuthorizeRequest, PostAuthorizeRequest ASP.NET先后触发这两个事件使安全模块对请求进行授权。 ResolveRequestCache, PostResolveRequestCache ASP.NET 先后触发这两个事件以使缓存模块利用缓存的内容对请求直接进行响应缓存模块可将响应内容进行缓存对于后续的请求直接将缓存的内容返回从而提高响应能力。 PostMapRequestHandler 对于访问不同资源类型ASP.NET具有不同的HttpHandler对其进行处理对于每个请求ASP.NET会通过扩展名选择匹配响应的HttpHandler类型成功匹配后该事件被触发。 AcquireRequestState, PostAcquestRequestState ASP.NET先后触发这两个事件使状态管理模块获取基于当前请求相应的状态如SessionState。 PreRequestHandlerExecute、PostRequestHandlerExecute ASP.NET 最终通过与请求资源类型相对应的 HttpHandler 实现对请求的处理在实行 HttpHandler 前后这两个事件被先后触发。 ReleaseRequestState、PostReleaseRequestState ASP.NET 先后触发这两个事件使状态管理模块释放基于当前请求响应的状态。 UpdateRequesetCache、PostUpdateRequestCache ASP.NET先后触发这两个事件以使缓存模块将HttpHandler处理请求得到的内容得以保存到输出缓存中。 LogRequest、PostLogRequest ASP.NET先后触发这两个事件为当前请求进行日志记录 EndRequest 整个请求处理完成后EndRequest事件会触发。
对于一个ASP.NET应用来说HttpApplication派生于Global.asax文件通过创建Global.asax文件对HttpApplication的请求处理行为进行定制。Global.asax采用一种很直接的方式实现了这样的功能这种方式不是方法重写或事件注册而是直接采用方法名匹配。在Global.asax中按照“Application_{Event Name}”的命名规则进行事件注册。 using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;namespace Huyoo.Backend
{// 注意: 有关启用 IIS6 或 IIS7 经典模式的说明// 请访问 http://go.microsoft.com/?LinkId9394801public class MvcApplication : System.Web.HttpApplication{protected void Application_Start(){AreaRegistration.RegisterAllAreas();WebApiConfig.Register(GlobalConfiguration.Configuration);FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);RouteConfig.RegisterRoutes(RouteTable.Routes);BundleConfig.RegisterBundles(BundleTable.Bundles);}}
}HttpModule
ASP.NET拥有一个具有高度的可扩展的引擎能处理不同资源类型的请求HttpModule是功不可没的。
当请求转入ASP.NET管道时最终负责处理该请求的是与请求资源类型相匹配的HttpHandler对象但是在HttpHandler正式工作之前。ASP.NET会先加载并初始化所有配置的HttpModule对象。HttpModule在初始化过程中会将一些回调操作注册到HttpApplication相应的事件中。在HttpApplication请求处理生命周期中的某个阶段相应的事件会被触发通过HttpModule注册的事件处理程序也得以执行。
所有的HttpModule都实现了具有如下定义的System.Web.IHttpModule接口其Init方法实现了针对自身的初始化。该方法接受一个HttpApplication对象有了这个对象事件注册就很容易了。 public interface IHttpModule
{void Dispose();void Init(HttpApplication context);
}ASP.NET提供了很多基础功能是通过相应的HttpModule实现的。除了系统定义的HttpModule之外可自定义HttpModule通过 Web.config 可很容易地将其注册到 Web 应用中。
OutputCacheModule 实现了输出缓存Output Caching的功能SessionStateModule 在无状态的HTTP协议上实现了基于会话Session的状态保持WindowsAuthenticationModule FormsAuthenticationModule PassportAuthenticationModule 实现了Windows、Forms、Passport三种典型的身份认证方式UrlAuthorizationModule FileAuthorizationModule 实现了基于URL和文件ACLAccess Control List的授权
HttpHandler
对于不同资源类型的请求ASP.NET会加载不同的Handler来处理比如.aspx页面与.asmx Web服务对应的Handler是不同的。
所有的HttpHandler都实现了具有如下定义的接口 System.Web.IHttpHandler定义其中的方法ProcessRequest提供了处理请求的实现。
另一个代表异步版本的HttpHandler的IHttpAsyncHandler接口继承自IHttpHandler它通过调用BeginProcessRequest/EndProcessRequest方法以异步的方式处理请求。 public interface IHttpHandler
{void ProcessRequest(HttpContext context);bool IsReusable{ get; }
}
public interface IHttpAsyncHandler:IHttpHandler
{IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData);void EndProcessRequest(IAsyncResult result);
}某些 HttpHandler 具有一个与之相关的HttpHandlerFactory后者实现了具有如下定义的接口 System.Web.IHttpHandlerFactory定义其中的方法GetHandler用于创建新的HttpHandler或获取已经存在的HttpHandler。 public interface IHttpHandlerFactory
{IHttpHandler GetHandler(HttpContext context, string requestType, string url, string pathTransslated);void ReleaseHandler(IHttpHandler handler);
}HttpHandler和HttpHandlerFactory的类型都可以通过相同的方式配置到 Web.config中。
在调用当前HttpContext的RemapHandler方法时指定一个具体的HttpHandler对象是为了让ASP.NET直接跳过默认的HttpHandler映射操作。此外由于这个默认的HttpHandler映射发生在HttpApplication的PostMapRequestHandler事件触发之前所以只有在这之前调用RemapHandler方法才有意义。 作者JunChow520 链接https://www.jianshu.com/p/85c7c931a3e7 来源简书 著作权归作者所有。商业转载请联系作者获得授权非商业转载请注明出处。