• 对ASP.Net的认识(一)


    ASP.Net 1.1/2.0/3.0/3.5/4.0的区别及新加特性

    ASP.Net 2.0相对ASP.Net 1.1增加了许多新的控件和功能,比如母版页(master page),登录控件,GridView,页面导航控件SiteMapDataSource,缓存控件,地址映射,URL映射,成员身份服务,配置文件服务,SQL缓存依赖项,AJAX,主题和外观,自动检测浏览器语言。

    Web Garden

    An application pool that uses more than one worker process is called a Web garden.

    Web Farm

    An application is hosted by multiple servers then it is said to be web farm environment.

    Http方法

    Get:请求指定的页面信息,并返回实体主体。
    Head:只请求页面的首部。
    Post:请求服务器接受所指定的文档作为对所标识的URI的新的从属实体。
    PUT:从客户端向服务器传送的数据取代指定的文档的内容。
    DELETE:请求服务器删除指定的页面。
    OPTIONS:允许客户端查看服务器的性能。
    TRACE:请求服务器在响应中的实体主体部分返回所得到的内容。
    PATCH:实体中包含一个表,表中说明与该URI所表示的原内容的区别。
    MOVE:请求服务器将指定的页面移至另一个网络地址。
    COPY:请求服务器将指定的页面拷贝至另一个网络地址。
    LINK:请求服务器建立链接关系。
    UNLINK:断开链接关系。
    WRAPPED:允许客户端发送经过封装的请求。
    Extension-mothed:在不改动协议的前提下,可增加另外的方法。 

    Cookie

    cookie是一种客户端机制,一般通过扩展Http协议来实现,服务器通过在HttpResponse的头部加入一段特殊的指令以使浏览器根据该指令生成cookie。客户端脚本如javascript和vbscript也可以生成cookie。在使用cookie时,浏览器首先会检查cookie所声明的作用范围,如果大于等于所要请求的资源的位置,则将cookie放在Http请求头上发给服务器。cookie的内容包括名字,值,过期时间,路径和域。路径和域一起构成cookie的作用范围。如果不设置过期时间,cookie的生命周期就是浏览器的会话时间,只要关闭浏览器,cookie就会消失,这时的cookie一般存储在内存中,也叫会话cookie,这种cookie根据浏览器的不同可以被多个浏览器共享,例如IE,只要是从原窗口上打开的新窗口(即使用了window.open),就可以和原窗口共享会话cookie。设置了过期时间的cookie,会被浏览器存储在硬盘上,只要不到过期时间都一直存在。

    Session

    session是一种服务器端机制,一般使用散列表(Hashtable)来实现Session的信息存储。当应用需要为客户端创建一个session时,服务器首先检查请求里是否包含一个该session的标识即session id,如果包含,则从已存在的session中找到该session(如果找不到则与不包含一样处理),如果不包含则创建一个新的session并生成与该session关联的唯一的session id(session id永远是唯一的),并将该session id放入HttpResponse中传回给客户端。

    客户端保存session id有三种方法,

    1、使用cookie

    2、将session id附加在URL上(作为路径附加或者作为查询字符串附加)

    3、在表单上添加一个隐藏字段来保存session id

    session一般只有在客户端请求服务器删除或者在过期时间到了以后才会被删除。关闭浏览器不会删除session,由于很多session机制的实现是通过将session id保存在会话cookie中,所以关闭浏览器会导致session id无法再被找到,从而让人产生错觉以为session被删除了,其实只要能够找到该session id,就可以再次使用该session。

    ASP.Net Session

    在ASP.Net中,会话状态通过HttpSessionState类的对象来实现,有HttpContext.Session和Page.Session,这两个对象其实指向的都是HttpContext.Session,而HttpContext.Session是由SessionStateModule负责创建的。HttpContext.Session可以用于单独的类,而Page.Session用于Code Behind的该Page类。HttpContext是通过Hashtable来保存Session的。

    HttpSessionState类其实是通过SessionDictionary的对象来实现的。

    public sealed class HttpSessionState 

    {

      private SessionDictionary _dict;

      public object this[string name]
      {

        get

        {

          return _dict[name];

        }

        set

        {

          _dict[name] = value;

        }

      }

    }

    而HttpSessionState的对象以及SessionDictionary的对象是在SessionStateModule类的实例方法CompleteAcquireState中创建的。

     在HttpApplication构造并且初始化SessionStateModule时,SessionStateModule会根据配置文件(如web.config)里的SessionState节点里的信息来初始化状态管理器(如InProc,StateServer或者SQLServer),通过调用InitModuleFromConfig方法来生成System.Web.SessionState.InProcStateClientManager / OutOfProcStateClientManager / SqlStateClientManager类的实例,这三个类都继承自StateClientManager抽象类,该抽象类实现了IStateClientManager接口。

    internal interface System.Web.SessionState.IStateClientManager.IStateClientManager

     {

      // 配置管理状态管理器

       void ConfigInit(SessionStateSectionHandler.Config config, SessionOnEndTarget onEndTarget);

       // 保存 SessionStateModule 实例供后面使用

       void SetStateModule(SessionStateModule module);

       void ResetTimeout(string id);

       void Dispose();

     

       void Set(string id, SessionStateItem item, bool inStorage);

     

      // 维护状态管理器内容

      IAsyncResult BeginGet(string id, AsyncCallback cb, object state);

      SessionStateItem EndGet(IAsyncResult ar);

      

      IAsyncResult BeginGetExclusive(string id, AsyncCallback cb, object state);

      SessionStateItem EndGetExclusive(IAsyncResult ar);

      void ReleaseExclusive(string id, int lockCookie);      

    ConfigInit方法用于根据配置文件中的信息进行初始化工作,并且将负责会话状态清除的SessionOnEndTarget对象绑定到会话管理器,对于OutOfProcess模式,还会初始化与外部服务器的连接,并通过一个 System.Web.Util.ResourcePool的对象来提供基于时间策略的资源池来维护连接。

    ResetTimout方法用于重置Session过期时间。对于InProc模式,该过期时间是通过 System.Web.Caching.CacheInternal 类的对象来使用的;对于StateServer模式,该过期时间通过OutOfProcStateClientManager的MakeRequest方法发给外部的StateServer;对于SQLServer模式,则是通过调用存储过程TempResetTimeout来更新ASPStateTempSessions表的Expires 字段。

    Dispose方法是释放状态管理器的资源,对于OutOfProcess模式,包括释放ResourcePool的对象以及该对象管理维护的资源。

    Set方法将SessionStateItem对象存储到与id相应的会话中,并根据inStorage的值来决定在发生异常时是否释放此会话的锁。

    状态管理器类是通过异步调用方法来获取数据的,对于获取数据的方法,InProcStateClientManager 通过缓存;OutOfProcStateClientManager 通过请求;SqlStateClientManager 通过 TempGetStateItemXXX 存储过程。

    SessionStateModule是用来创建并且管理会话的,它提供包括生成SessionID,从保存Session数据的地方获取Session数据,将Session数据绑定在HttpContext上(即生成HttpContext.Session),以及在请求成功处理完成后将更新的Session数据放回保存Session数据的地方等功能。

    SessionStateModule先初始化状态管理器对象,然后创建HttpSessionState对象。

    SessionStateModule的OnReleaseState方法会在适当的时候将SessionDictionary对象写回状态管理器。

    HttpSessionState的维护操作是通过SessionStateModule调用状态管理器类的对象的接口来完成的。

    Session的状态管理模式有四种,

    1、InProc:会话存储在内存中,在IIS进程中管理,可以存储任何对象,无需序列化和反序列化。

    2、StateServer:会话存储在内存中,在StateServer进程(aspnet_state.exe)中管理,可以与Web服务器不是同一台机器,只能存储可以序列化的对象,需要序列化和反序列化。

    3、SQLServer:会话存储在临时数据库(TempDB)或者永久数据库(ASPState数据库)中,由SQLServer管理,可以与Web服务器不是同一台机器,TempDB会在SQLServer重启时被清空(Session会丢失),只能存储可以序列化的对象,需要序列化和反序列化。

    4、Off:不启用会话状态管理。

    当代码读取Session值时,其实是从本地(即Web服务器)的内存中读取的,是HttpSessionStateModule读取Session值时在本地内存中保留的一份拷贝。HttpSessionStateModule在操作Session值时为了能够处理并发问题,实现了读/写锁的机制,当Session被读锁锁住时,只能读不能写,而当Session被写锁锁住时,只有当前拥有该锁的请求能够操作该Session,其他请求将全部被锁住。在页面上,@Page有个属性叫EnableSessionState,当该属性设为true(为属性默认值)时,该页面请求有更新和读取Session的权限,当值为ReadOnly时,则只有读取Session的权限。

    使用OutOfProcess的Session状态管理器(StateServer和SQLServer),将会有很大的开销用于序列化和反序列化Session值以及拷贝数据到本地内存中,不过可以将Session状态管理与工作者进程分离,从而当工作者进程出现问题时,Session不会有问题。另外,由于OutOfProcess的Session状态管理可以使Session保存在与Web服务器不同的机器上,从而在一定程度上可以解决内存资源限制的问题。序列化存储对象时,对于基本类型,会使用经过优化的内部序列化器,对于其他类型的对象,则使用二进制序列化器。内部序列化器会在第一个字节里标示类型,对于长度变化的类型(如string),则会在流之前记录一个长度值。序列化非基本类型比序列化基本类型开销大,因此序列化过多的非基本类型会严重影响系统性能。

    InProc的Session状态管理器其实是把Session值存放在Cache对象的一个private slot里,不过由于Cache对象的private slot是不暴露给外界的,所以无法通过代码直接从这个slot里获取Session值。

    ASP.Net Session只有在第一个Session值被添加时,它的生命周期才被认为开始。当没有Session值被存入时,每次请求都会产生一个新的Session ID,直到第一个Session值被存入,这是由于当Session状态与当前请求关联时,HttpSessionStateModule会根据已知Session ID去寻找对应的Session,如果找不到,则会生成一个新的Session ID与当前请求关联,而对于空的Session,由于并未保存,所以肯定是找不到的。但是对于实现了Session_OnStart事件处理器的应用,即使是空的Session也会被保存,所以对于这样的应用,在第一次请求生成Session ID后,这个Session ID就会保持不变,即使Session过期也一样。Session_OnStart方法在一个新的Session开始或者一个老的Session过期后会被触发。Session_OnEnd只有在InProc模式下会被触发,对于OutOfProcess模式,它永远不会被触发。Session ID是由15组数字组成,每个数字占一个字节。当HttpSessionStateModule生成Session ID后,如果是cookieless的Session,该Http Module还会把新生成的Session ID自动加入到URL中,以便之后的处理。

    使用cookie保存Session ID可以保证Session ID在一个绝对的URL被调用后仍然存在,但是cookieless的Session则无法做到,不过可以使用HttpResponse类的实例方法ApplyAppPathModifier在某个范围内解决这一问题,该方法接受一个URL作为参数,并返回一个绝对的URL,但它会将Session ID嵌在这个绝对的URL中从而使Session信息不会丢失。但是把Session ID存放在URL中会有一个问题,即当该URL被拷贝粘贴到另一个客户端后,另一个客户端可与当前客户端共用一个Session,从而导致问题。

    ASP.Net Cache

    HttpRuntime.Cache,HttpContext.Cache,Page.Cache其实指向的是同一个Cache对象,Page.Cache指向HttpContext.Cache,HttpContext.Cache指向HttpRuntime.Cache。HttpRuntime.Cache是一个静态属性,它指向HttpRuntime._theRuntime._cachePublic。另外,HttpRuntime.Cache可用于非Web应用,而其他两个不行。

    public static Cache Cache
    {
      get
      {
        if (AspInstallDirectoryInternal == null)
        {
          throw new HttpException(SR.GetString("Aspnet_not_installed", new object[]     { VersionInfo.SystemWebVersion }));
        }
        Cache cache = _theRuntime._cachePublic;
        if (cache == null)
        {
          CacheInternal cacheInternal = CacheInternal;
          CacheSection cacheSection = RuntimeConfig.GetAppConfig().Cache;
          cacheInternal.ReadCacheInternalConfig(cacheSection);
          _theRuntime._cachePublic = cacheInternal.CachePublic;
          cache = _theRuntime._cachePublic;
        }
        return cache;
      }
    }

    ASP.Net还提供了页面输出缓存,用于存储需要大量时间和资源生成的但又不频繁改变的页面,它有两种方法设置,一个是用@OutputCache指令,它包括CacheProfile、NoStore、Duration、Shared、Location、SqlDependency、VaryByControl、VaryByCustom、VaryByHeader和VaryByParam这10个属性。另一个是用页面输出缓存API,主要指HttpCachePolicy类,通过Response.Cache来获得该类的一个实例,然后调用相应的方法进行配置,方法包括SetExpires、SetLastModified、SetSlidingExpiration、SetOmitVaryStar和SetCacheability等。

    ASP.Net Application

    当web.config,global.asax和bin文件夹下任何文件的改动,都会导致当前的Application重启。 

    RuntimeConfig

    RuntimeConfig是一个用于加载配置文件(如web.config和app.config)的类,它被用于加载并读取配置文件里的信息,并帮助其他类的对象通过配置文件里的信息进行初始化。

    CLR和AppDomain

    当在进程中要执行托管代码时,需要加载CLR,一个Windows进程中只能加载一个版本的CLR,一旦CLR被加载到进程中,就无法被卸载,要想卸载只能终止进程。AppDomain是一个应用执行的独立环境,它存在于CLR中,一个进程里可以有多个AppDomain,该进程中的线程并不局限于任何一个AppDomain,但在特定的时间里,一个线程仅在一个AppDomain里运行。AppDomain是相互隔离的(包括对象,方法,数据等),每个AppDomain有自己的安全策略和配置策略。一个AppDomain发生异常或者崩溃不会影响其他AppDomain,它是一种“逻辑进程”。每个AppDomain都有自己的局部存储区(由.Net框架分配)。同一个程序集(Assembly)可以被多个AppDomain加载,一般情况下在每个AppDomain里它都有自己的一个实例,当这类程序集被加载到某个AppDomain后,要想卸载该程序集,必须卸载该AppDomain。不过有些特殊的程序集会被所有的AppDomain共享(比如MSCorLib.dll),这类特殊的程序集被加载在CLR中,只有当进程终止时才会被卸载。CLR初始化时会创建一个AppDomain,这个AppDomain就是Default AppDomain,它只有在进程终止时才会被卸载。

    ISAPI(Internet Server API)

    ISAPI是一套Win32 API,用于增强IIS的功能,是IIS与Web应用或平台的纽带。它分为ISAPI扩展(ISAPI Extension, 如HttpHandler)和ISAPI筛选(ISAPI Filter,如HttpModule)。ISAPI扩展用于处理HTTP请求,ISAPI筛选用于处理某些特定的事件,预处理传入的HTTP请求或者再加工传出的HTTP结果。

    ISAPIRuntime

    ISAPIRuntime实现了IISAPIRuntime接口。IISAPIRuntime接口如下:

    [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("08a2c56f-7c16-41c1-a8be-432917a1a2d1")]
    public interface IISAPIRuntime
    {
        
    void StartProcessing();
        
    void StopProcessing();
        [
    return: MarshalAs(UnmanagedType.I4)]
        
    int ProcessRequest([In] IntPtr ecb, [In, MarshalAs(UnmanagedType.I4)] int useProcessModel);
        
    void DoGCCollect();
    }

    其中,ProcessRequest方法里有一个指针参数ecb,它是ISAPIRuntime对aspnet_isapi.dll的引用,通过这个引用,ISAPIRuntime可以从aspnet_isapi.dll获取请求信息并且可以把结果传回给aspnet_isapi.dll。ProcessRequest方法会根据IIS版本的不同创建一个继承自ISAPIWorkerRequest类的非抽象子类的实例(ISAPIWorkerRequestInProc/ISAPIWorkerRequestOutOfProc(IIS 5.x),ISAPIWorkerRequestInProcForIIS6(IIS 6),ISAPIWorkerRequestInProcForIIS7(IIS 7)),该实例将ecb进行了封装,使其可以用于托管环境中。aspnet_isapi.dll对ISAPIRuntime的调用是异步的,它调用后就立即返回,不过ecb会一直保留,直到请求处理完成后才释放。

     

    ISAPIWorkerRequest

    ISAPIWorkerRequest是一个抽象类,继承自HttpWorkerRequest抽象类,该抽象类定义了由托管代码处理请求信息的基本辅助方法和枚举。通过生成这个继承自ISAPIWorkerRequest类的非抽象子类的实例,aspnet_isapi.dll从非托管环境转入了托管环境。

    HttpRuntime

    HttpRuntime是ASP.Net管道的入口点,每个AppDomain里只能加载一个HttpRuntime。HttpRuntime在处理多个请求时,会将所有请求排队,然后顺次执行。HttpRuntime的ProcessRequestInternal方法的主要流程:

    1、创建HttpContext对象

    2、调用EnsureFirstRequestInit方法对第一次请求进行初始化,所做的工作包括将web.config中的配置读到RuntimeConfig对象中,从bin目录中加载所有dll文件。

    3、创建HttpWriter对象

    4、调用HttpApplicationFactory的GetApplicationInstance方法获得HttpApplication对象。在GetApplicationInstance方法中有三个关键方法,HttpApplicationFactory._theApplicationFactory.EnsureInited();
    HttpApplicationFactory._theApplicationFactory.EnsureAppStartCalled(context);
    HttpApplicationFactory._theApplicationFactory.GetNormalApplicationInstance(context);

    EnsureInited方法用于检查HttpApplicationFactory对象是否被初始化,如果没有则调用HttpApplicationFactory.Init()方法进行初始化。在Init方法中,会获取global.asax文件的完整路径,并对App_GlobalResources目录、App_WebReferences目录和App_Code目录进行编译,在编译完这三个目录后,会对global.asax进行编译,并在C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files目录中生成App_global.asax.xxxxxxxx.dll文件,编译生成的类名为ASP.global_asax,继承自HttpApplication。

    EnsureAppStartCalled方法会触发ApplicationOnStart事件,并会执行global.asax中的Application_Start事件处理方法。

    GetNormalApplicationInstance方法会获得一个HttpApplication对象,如果无法从对象池中获得则会创建一个HttpApplication对象(调用HttpRuntime.CreateNonPublicInstance方法)。在创建时会根据当前对象的_theApplicationType进行创建,如果没有global.asax文件则类型为HttpApplication,否则类型为ASP.global_asax。创建完HttpApplication对象后会调用该对象的InitInternal方法进行初始化,包括以下几个步骤,

    a) InitModules():根据Web.Config的设置,创建相应的HttpModules。

    b) HookupEventHandlersForAppplicationAndModules:根据发生的事件,调用HttpApplication实例中相应的事件处理函数。

    c)

    HttpContext

    对于每个请求,HttpRuntime都会创建一个HttpContext对象,HttpContext对象的生命周期是到请求处理完毕或者处理超时。

    HttpApplication

    HttpApplication对象是通过HttpApplicationFactory类来获得,HttpApplicationFactory内部维护了一个HttpApplication对象池(通过Stack形式实现),用于降低创建HttpApplication对象的开销,如果池中没有可以使用的HttpApplication对象,则它会创建并初始化一个HttpApplication对象,从下面的代码中可以看出HttpApplication其实是由HttpRuntime来创建的,不过创建完后会交给HttpApplicationFactory来管理。

    internal static IHttpHandler HttpApplicationFactory.GetApplicationInstance(HttpContext ctxt)

      处理定制应用程序

      处理调试请求

      判断是否需要初始化当前 HttpApplicationFactory 实例
      return HttpApplicationFactory._theApplicationFactory.GetNormalApplicationInstance(ctxt);

    private HttpApplication HttpApplicationFactory.GetNormalApplicationInstance(HttpContext context)
    {
      HttpApplication app = null;

      尝试从已施放的 Web 应用程序实例队列中获取

      if(app == null)
      {
        app = (HttpApplication)System.Web.HttpRuntime.CreateNonPublicInstance(this._theApplicationType);

        app.InitInternal(context, this._state, this._eventHandlerMethods);
      }

      return app;
    }

    IIS 5.x处理请求的流程

    当客户端向服务器发送一个请求后,请求会被inetinfo.exe接收并进行检查(inetinfo.exe是运行IIS的进程,该进程中有一个Windows Service,叫World Wide Web Publishing Service,即W3SVC,该服务用于Http请求的监听,工作进程的管理和配置管理),根据请求的资源文件的后缀名(扩展名)来判断该资源是否为静态资源,如果是静态资源,则直接通过IIS处理(IIS只能处理静态资源),获取该资源并返回结果(Http Response)。如果是动态资源,则通过IIS的脚本映射(Script Map,可以在IIS配置中设置,Virtual Directory[Home Directory] ---> Configuration ---> Mapping),根据后缀名加载相应的ISAPI并将请求交给相应的ISAPI(对于ASP.Net是aspnet_isapi.dll)。对于ASP.Net,aspnet_isapi.dll首先会检测aspnet_wp.exe是否已存在(aspnet_wp.exe是ASP.Net工作者进程,aspnet_isapi.dll会根据一些标准对它进行回收,这些标准存放在machine.config文件里,包括应用程序的生命周期,等待或服务的队列长度,空闲时间等,),如果该进程不存在,则会创建一个该进程(在进程初始化的时候,首先加载CLR,然后CLR调用AppDomainFactory(asp.net 1.1及之前版本使用该类创建AppDomain,asp.net 2.0及之后版本使用ApplicationManager类来创建AppDomain)的Create方法来创建AppDomain和ISAPIRuntime的实例。对于Web应用的初次请求,CLR会为该Web应用创建一个AppDomain,同时也创建一个ISAPIRuntime的实例。ISAPIRuntime用于将aspnet_isapi.dll从非托管环境转入到托管环境。在AppDomain创建完后,它会加载HttpRuntime类,该类有个静态属性是自己的实例,是通过Singleton模式实现的,名字叫_theRuntime,该对象用于调用一些实例方法),然后aspnet_isapi.dll通过命名管道(Named Pipeline,是一种Win32机制,用于跨进程传输数据)异步调用ISAPIRuntime(它在aspnet_wp.exe进程中相应的AppDomain中)中的ProcessRequest方法来生成一个继承自ISAPIWorkerRequest类的非抽象子类的实例,从而使请求从aspnet_isapi.dll传到了AppDomain的托管环境中(该实例包含需要处理的所有请求信息),然后将该实例交给HttpRuntime来处理(调用HttpRuntime.ProcessRequestNoDemand静态方法,参数就是生成的继承自ISAPIWorkerRequest类的非抽象子类的实例),HttpRuntime随后通过实例方法ProcessRequestInternal来创建HttpContext对象,并且通过该HttpContext对象创建HttpApplication对象,处理完后返回给客户端。即HttpRequest --> inetinfo.exe --> ASPNET_ISAPI.dll --> ASPNET_WP.exe --> ISAPIRuntime ---> HttpRuntime --> HttpApplication Factory --> HttpApplication --> HttpModule --> HttpHandler Factory --> HttpHandler --> HttpModule

    IIS 6.0处理请求的流程

    当客户端向服务器发送一个请求后,请求会被HTTP.SYS组件(该组件负责侦听,检查,转发Http请求,并且将处理结果发送出去)接收,并对该请求进行检查,根据请求的URL发送给相应的应用程序池中的某个工作者进程(工作者进程是可执行程序W3WP.EXE运行时所生成的一个进程,一个工作者进程可以管理一个或多个ASP.Net应用程序,它运行于一个应用程序池中。一般一个应用程序池中只有一个工作者进程,但也可以通过配置使一个应用程序池中有多个工作者进程,这时这个应用程序池被称为Web园[Web Garden]),工作者进程会根据页面的后缀加载相应的页面处理程序(对于ASP.Net会加载aspnet_isapi.dll),然后将请求转给该页面处理程序,该页面处理程序会启动一个复杂的由多个步骤和组件组成的处理流程,这个处理流程是基于管道模式(Pipeline),先由管道中的模块(如HttpModule)处理,然后由处理程序处理(如HttpHandler),再由管道中的模块处理(如HttpModule),最后形成结果。然后把结果转发给HTTP.SYS,由它发送出去。对于ASP.Net,在启动处理流程前,会先加载.Net CLR,并且为该ASP.Net站点创建一个应用程序域。 

    HttpHandler和HttpModule都是应用程序级的事件处理对象, 一个实现了IHttpHandler接口,一个实现了IHttpModule接口。它们都可以对Http Request进行处理。HttpHandler是对页面请求进行真正的处理,实现了IHttpHandler接口必须实现ProcessRequest方法和IsReusable属性,其中IsReusable属性用来决定这个HttpHandler对象是否可以处理接下来的其他请求。HttpModule通常是对一些特定的事件进行处理,实现了IHttpModule接口必须实现两个方法Init和Dispose。自定义的HttpModule一般用于全局的身份/权限验证、自定义网站访问/操作日志的记录、由于管理/调试等目的对站点进行监控追踪等。HttpHandler如果需要读写Session,必须实现IRequireSessionState接口。可以在web.config或者machine.config中配置自定义的HttpModule和HttpHandler。

    对于HttpModule,配置方法如下:

    <httpModules>

          <add name="test" type="MyHttpModuleTest.MyHttpModule, MyHttpModules"/>

    </httpModules>

    其中,'MyHttpModuleTest.MyHttpModule'是类型的命名空间,'MyHttpModules'是程序集名。

    对于HttpHandler,配置方法如下:

    <httpHandlers>

        <add verb="*" path="*.cc" type="MyHandler.MyHttpHandler, MyHandlers"/>

    </httpHandlers>

    其中,verb属性决定该HttpHandler处理哪些Http方法,如GET,POST,HEAD等,*表示处理所有Http方法。path属性决定该HttpHandler处理哪些类型的文件,如*.aspx,*.asp,*.config,*.cs等,如果是所有类型的文件,则使用path="*"。

    HttpHandler和HttpModule的区别

    1. 顺序:HttpModule有些方法是在HttpHandler之前被调用,也有些方法是在HttpHandler之后被调用。所以一般顺序为HttpModule,HttpHandler,HttpModule。

    2. 处理文件的类型:HttpModule处理所有的文件类型,HttpHandler只处理ASP.Net注册过的文件类型。 

    3. HttpHandler是ISAPI扩展,HttpModule是ISAPI筛选。

    ASP.Net事件层级

    1. 应用程序级

    2. 页面级

    3. 控件级

    @Page中AutoEventWireup属性

    AutoEventWireup属性用于决定是否自动将页面级事件与事件处理方法相关联。如果为true,则自动关联,缺点是方法名被限制,必须使用标准的方法名,如"Page_Load"。如果为false,那么需要显式地将事件处理方法加入事件委托中,如"this.Load += new System.EventHandler(this.Page_Load);"

    Get和Post的区别

    Get被设计用于信息获取,应该是安全和幂等的,安全指它只取信息不进行修改,幂等是指对于多个请求返回的结果是一样的。

    Post被设计用于创建和修改服务器上的资源。

    表单提交时,默认方法是Get。

    Get通过URL来传递数据,长度受限制,根据浏览器的不同最大长度限制不同,一般最长为1024字节,存放在Http请求的头上,用Request.QueryString来获取传递的数据,Get只支持ASCII。

    Post将数据存放在Http请求的主体中,可以支持比Get大许多倍的数据,用Request.Form来获取传递的数据,Post支持整个ISO10646字符集。SOAP是基于Post方式实现的。

    另外,Head请求方式只返回Http的头信息。

    ashx文件

    ashx文件用于写web handler,使用ashx文件可以专注于编程而无需管相关的web技术。ashx文件中的类继承自IHttpHandler,因而必须包含IsReusable属性及ProcessRequest方法,ashx文件其实完全可以用aspx文件替代,但ashx文件比aspx文件性能高一点,因为它免去了aspx的页面解析及页面处理的过程,它适用于生成动态图片和动态文本之类的某一具体功能的操作,但对于一些复杂的功能操作,如处理回发控件的事件则不合适。

  • 相关阅读:
    notepad++ 编辑器链接地址可点击
    window的cmd窗口运行git
    php update for mac
    sublime打开文件时自动生成并打开.dump文件
    不能设置sublime text 2 为默认编辑器
    sublime text 2 配置文件
    Compass被墙后如何安装安装
    everything搜索工具小技巧
    Ubuntu安装已经下载好的文件包
    Flutter 异步Future与FutureBuilder实用技巧
  • 原文地址:https://www.cnblogs.com/loofywang/p/MyUnderstandingOfASPNET1.html
Copyright © 2020-2023  润新知