较为详细的整个请求处理流程

Application: BeginRequest
Application: PreAuthenticateRequest
Application: AuthenticateRequest
Application: PostAuthenticateRequest
Application: PreAuthorizeRequest
Application: AuthorizeRequest
Application: PostAuthorizeRequest
Application: PreResolveRequestCache
Application: ResolveRequestCache
Application: PostResolveRequestCache
Application: PreMapRequestHandler
Page: Construct
Application: PostMapRequestHandler
Application: PreAcquireRequestState
Application: AcquireRequestState
Application: PostAcquireRequestState
Application: PreRequestHandlerExecute
Page: AddParsedSubObject
Page: CreateControlCollection
Page: AddedControl
Page: AddParsedSubObject
Page: AddedControl
Page: ResolveAdapter
Page: DeterminePostBackMode

Page: PreInit
Control: ResolveAdapter
Control: Init
Control: TrackViewState
Page: Init
Page: TrackViewState
Page: InitComplete
Page: LoadPageStateFromPersistenceMedium
Control: LoadViewState
Page: EnsureChildControls
Page: CreateChildControls
Page: PreLoad
Page: Load
Control: DataBind
Control: Load
Page: EnsureChildControls
Page: LoadComplete
Page: EnsureChildControls
Page: PreRender
Control: EnsureChildControls
Control: PreRender
Page: PreRenderComplete
Page: SaveViewState
Control: SaveViewState
Page: SaveViewState
Control: SaveViewState
Page: SavePageStateToPersistenceMedium
Page: SaveStateComplete
Page: CreateHtmlTextWriter
Page: RenderControl
Page: Render
Page: RenderChildren
Control: RenderControl
Page: VerifyRenderingInServerForm
Page: CreateHtmlTextWriter
Control: Unload
Control: Dispose
Page: Unload
Page: Dispose
Application: PostRequestHandlerExecute
Application: PreReleaseRequestState
Application: ReleaseRequestState
Application: PostReleaseRequestState
Application: PreUpdateRequestCache
Application: UpdateRequestCache
Application: PostUpdateRequestCache
Application: EndRequest
Application: PreSendRequestHeaders
Application: PreSendRequestContent

Master Page的加载顺序

1、Master page中的用户控件的page_init

2、aspx页面中的用户控件的page_init

3、Master page的page_init

4、aspx页面的page_init

5、aspx页面的page_load

6、Master page的page_load

7、Master page中的用户控件的page_load

8、aspx页面中的用户控件的page_load

其实Master Page可以看成是一个控件。

何时使用DataGrid/DataList/Repeater

实现了IEnumerable接口的类的对象可以成为这三种数据控件的数据源。

DataGrid最终会生成一个table,所以DataGridItem类继承自TableRow类。而Repeater最终生成的控件是用户自定义的,所以RepeaterItem类与TableRow类没有任何关系。DataGrid和DataList继承自WebControl类,而Repeater继承自Control类,WebControl类包含一些设置样式的属性,如BackColor,ForeColor,CssStyle,BorderStyle等,而Repeater样式的设置必须在它的Template里完成。

DataGrid有很多功能但欠缺灵活性,使用DataGrid很便捷,因为很多功能都已经封装好,只需要设置下相应的属性即可,但也正因为这个好处,使得DataGrid比较呆板,只能使用已经做好的功能,修改现有功能会比较麻烦,而且DataGrid最终生成的是一个table,如果想生成多个table或者div,DataGrid就无能为力了。DataGrid的性能是最差的因为DataGrid会把几乎所有内容都放入它的ViewState中,如果要使用DataGrid的Sort,Paging和Edit功能就不能禁掉ViewState,这会使ViewState大到足以严重影响性能的程度。

DataList比起DataGrid更加灵活,它可以使一行有多条记录,既可以使用table也可以使用span,不过有许多功能DataList并没有实现,需要开发人员自己实现,这样虽然会让开发人员花费更多时间但增强了灵活性,DataList的性能比起DataGrid要好。

Repeater是最灵活的,但对开发人员的要求也是最高的,它会花费最多的开发时间,但可以实现很多DataGrid和DataList无法实现的效果和功能,而且性能是最好的。

Page继承自TemplateControl并且实现了IHttpHandler接口,TemplateControl继承自Control,Page本身就是个HttpHandler。

Page处理Request的流程大致如下代码所述,也就是页面处理的流程。

private void ProcessRequestMain(bool includeStagesBeforeAsyncPoint, bool includeStagesAfterAsyncPoint)
{
        // 1. PreInit
        this.PerformPreInit();
        // 2. Init
        this.InitRecursive(null);
        this.OnInitComplete(EventArgs.Empty);

// 对于Postback,插入下面处理
        if (this.IsPostBack)
        {
            // 加载ViewState和ControlState,进行场景恢复
            this.LoadAllState();
            // 第一次处理PostData
            this.ProcessPostData(this._requestValueCollection, true);
        }

// 3. PreLoad
        this.OnPreLoad(EventArgs.Empty);
        // 4. Load
        this.LoadRecursive();

// 对于Postback,插入下面处理
        if (this.IsPostBack)
        {
            // 第二次处理PostData
            this.ProcessPostData(this._leftoverPostData, false);
            // 如果PostData表面某个Control数据发生变化,那么RaisePostDataChanged事件
            this.RaiseChangedEvents();
            // RaisePostBackEvent
            this.RaisePostBackEvent(this._requestValueCollection);
        }

this.OnLoadComplete(EventArgs.Empty);

// 对于CallBack,RaiseCallBackEvent
        if (this.IsPostBack && this.IsCallback)
        {
            this.PrepareCallback(callbackControlID);
        }
        else if (!this.IsCrossPagePostBack)
        {
            // 5. PreRender
            this.PreRenderRecursiveInternal();
        }
   
        // 对于CallBack, Render出CallBack的结果
        if (this.IsCallback)
        {
            this.RenderCallback();
        }
        else if (!this.IsCrossPagePostBack)
        {
            this.PerformPreRenderComplete();
            
            // 6. SaveViewStae和ControlState
            this.SaveAllState();
            this.OnSaveStateComplete(EventArgs.Empty);

// 7. Render 整个Control
            this.RenderControl(this.CreateHtmlTextWriter(this.Response.Output));
        }
}
其中,PerformPreInit方法代码如下,可以发现PreInit时主要初始化Themes,加载MasterPage。

private void PerformPreInit()
{
    this.OnPreInit(EventArgs.Empty);
    this.InitializeThemes();
    this.ApplyMasterPage();
    this._preInitWorkComplete = true;
}

Page以及每个Control都有个ControlState属性,该属性用于记录Page处理到哪个阶段了,例如Init阶段结束时,这个属性会被赋值ControlState.Initialized,从而表明Init阶段的结束。这个属性会被用于很多地方,例如当添加一个动态控件时,父控件的AddedControl方法就会检查这个属性,如果已经过了Init阶段,则直接初始化添加的控件。ControlState和ViewState最大的区别是ControlState是无法被禁止的,并且ControlState里有个ArrayList,这个ArrayList保存了需要处理PostBackData的Control的ID,当处理PostBackData时就会从这个ArrayList里获取需要处理的Control的ID。

下面是Control.AddedControl方法的代码,

protected internal virtual void AddedControl(Control control, int index)
{
    // 1. 初始化Page,Parent,NameContainer,ID
    control._parent = this;
    control._page = this.Page;
    control.flags.Clear(0x20000);
    Control namingContainer = this.flags[0x80] ? this : this._namingContainer;
    if (namingContainer != null)
    {
        control.UpdateNamingContainer(namingContainer);
        if ((control._id == null) && !control.flags[0x40])
        {
            control.GenerateAutomaticID();
        }
        else if ((control._id != null) || ((control._occasionalFields != null) && (control._occasionalFields.Controls != null)))
        {
            namingContainer.DirtyNameTable();
        }
    }

// 2. 判断当前Control所在的页面生命周期阶段,然后对于新加入的Control进行补充调用
    if (this._controlState >= ControlState.ChildrenInitialized)
    {
        control.InitRecursive(namingContainer);
        if (((control._controlState >= ControlState.Initialized) && (control.RareFields != null)) && control.RareFields.RequiredControlState)
        {
            this.Page.RegisterRequiresControlState(control);
        }
        if (this._controlState >= ControlState.ViewStateLoaded)
        {
            object savedState = null;
            if ((this._occasionalFields != null) && (this._occasionalFields.ControlsViewState != null))
            {
                savedState = this._occasionalFields.ControlsViewState[index];
                if (this.LoadViewStateByID)
                {
                    control.EnsureID();
                    savedState = this._occasionalFields.ControlsViewState[control.ID];
                    this._occasionalFields.ControlsViewState.Remove(control.ID);
                }
                else
                {
                    savedState = this._occasionalFields.ControlsViewState[index];
                    this._occasionalFields.ControlsViewState.Remove(index);
                }
            }
            control.LoadViewStateRecursive(savedState);
            if (this._controlState >= ControlState.Loaded)
            {
                control.LoadRecursive();
                if (this._controlState >= ControlState.PreRendered)
                {
                    control.PreRenderRecursiveInternal();
                }
            }
        }
    }
}
Control的卸载也是递归调用的。

对于需要用ASP.Net进行身份验证的页面,即使所有内容是静态的,也需要将后缀名改成aspx而不能用html,这是因为html将不会被ASP.Net的ISAPI所处理,也就无法进行身份验证。

aspx页面一般有ASP.Net自带的页处理程序来处理,它是Http处理程序中的一种,另外还有处理asmx的Web服务处理程序,如果需要针对特别的后缀名进行特别处理,需要创建一个自定义的Http处理程序,然后在IIS中将扩展名映射到ASP.Net的ISAPI中,并且在Web.config中注册这个处理程序。在Web.config中的注册如下代码所示

<configuration>
    <system.web>
        <httpHandlers>  <add verb="*" path="*.sample" type="MyHandler"/></httpHandlers>
    </system.web>
</configuration>

创建一个自定义的Http处理程序,有两种方式,

1、实现IHttpHandler接口创建同步处理程序

2、实现IHttpAsyncHandler接口创建异步处理程序

这个两个接口都需要实现IsReusable属性和ProcessRequest方法。IsReusable属性用于确定HttpHandlerFacotry对象(接收请求并调用相应的处理程序的对象)是否可以把该处理程序放入池中以便重复使用来提高性能,如果不可以的话,那么每次都要创建一个该处理程序的实例。ProcessRequest方法用于处理单个Http请求。如果Http处理程序的扩展名为ashx,那么这个处理程序会自动注册到IIS和ASP.Net中。异步处理程序可以启动一个外部进程,ASP.Net会将用于外部进程的线程放回线程池中以提高性能,直至外部进程处理结束进行回调为止。异步处理程序还必须实现BeginProcessRequest和EndProcessRequest方法。

另外可以通过实现IHttpHandlerFactory接口来自定义HttpHandlerFactory,这样做更具有灵活性,可以根据Http请求的具体命令(HttpContext.Request.RequestType,如PUT,GET,POST等)做一些处理,例如对于不同的命令调用不同的处理程序。在创建了自定义的HttpHandlerFactory以后需要在Web.config和IIS中进行注册。在Web.config中添加如下代码

<configuration>
  <system.web>
    <httpHandlers>      <add verb="GET,POST" path="*.sample" type="MyHandlerFactory" />    </httpHandlers>
  </system.web>
</configuration>
在IIS中需要对文件后缀名与ASP.Net的ISAPI进行映射。

ApplicationManager类在asp.net 2.0及之后版本用于创建并管理AppDomain。

对ASP.Net的认识(三)的更多相关文章

  1. ASP.NET MVC 视图(三)

    ASP.NET MVC 视图(三) 前言 上篇对于Razor视图引擎和视图的类型做了大概的讲解,想必大家对视图的本身也有所了解,本篇将利用IoC框架对视图的实现进行依赖注入,在此过程过会让大家更了解的 ...

  2. ASP.NET MVC 路由(三)

    ASP.NET MVC路由(三) 前言 通过前两篇的学习会对路由系统会有一个初步的了解,并且对路由系统中的Url规则有个简单的了解,在大家的脑海中也有个印象了,那么路由系统在ASP.NETMVC中所处 ...

  3. ASP.NET MVC 过滤器(三)

    ASP.NET MVC 过滤器(三) 前言 本篇讲解行为过滤器的执行过程,过滤器实现.使用方式有AOP的意思,可以通过学习了解过滤器在框架中的执行过程从而获得一些AOP方面的知识(在顺序执行的过程中, ...

  4. Asp.Net中的三种分页方式

    Asp.Net中的三种分页方式 通常分页有3种方法,分别是asp.net自带的数据显示空间如GridView等自带的分页,第三方分页控件如aspnetpager,存储过程分页等. 第一种:使用Grid ...

  5. 小白开学Asp.Net Core《三》

    小白开学Asp.Net Core<三> ——界面 我胡汉三再次又回来了(距离上篇时间有点长),今天抽时间将最近对框架采用的后台界面做个记录 1.先上图 (图一) (图二) 2.界面说明 后 ...

  6. ASP.NET MVC 第三回 Controller与View

    这节我们让ASP.NET MVC真正的跑起来 一.新建Controller 首先我们自己新建一个新的Controller在Controllers上点右键,添加,Controller选项   之后出现一 ...

  7. Pro ASP.NET MVC –第三章 MVC模式

    在第七章,我们将创建一个更复杂的ASP.NET MVC示例,但在那之前,我们会深入ASP.NET MVC框架的细节:我们希望你能熟悉MVC设计模式,并且考虑为什么这样设计.在本章,我们将讨论下列内容 ...

  8. ASP.Net 中的三种控件

    ---恢复内容开始--- 第一种:HTML控件 ASP.Net把HTML控件当成普通字符串渲染到浏览器端,不去检查正确性.无法在服务器端进行处理. 比如: <input111 type=&quo ...

  9. Asp.Net中的三种分页方式总结

    本人ASP.net初学,网上找了一些分页的资料,看到这篇文章,没看到作者在名字,我转了你的文章,只为我可以用的时候方便查看,2010的文章了,不知道这技术是否过期. 以下才是正文 通常分页有3种方法, ...

  10. ASP.NET MVC 4 (三) 过滤器

    先来看看一个例子演示过滤器有什么用: public class AdminController : Controller { // ... instance variables and constru ...

随机推荐

  1. android安卓 SQLite教程:内部架构及SQLite使用办法

    SQLite 介绍 SQLite一个非常流行的嵌入式数据库,它支持SQL语言,并且只利用很少的内存就有很好的性能.由于JDBC不适合手机这种内存受限设备,所以Android开发人员需要学习新的API ...

  2. HTML之一 符号实体

    符号实体和”语言代码“以及”字符集“无关.

  3. 如何理解js

    1.js/dom功能 2.performance 3.code organization 4.tools and flow 如何理解js代码,代码即业务. 如何快速理解代码业务.

  4. linux修改history

    1.cat ~/.bash_history cat -n  ~/.bash_history [以行数的形式查看] 2.history | more Enter 键盘  ----------一行一行 空 ...

  5. Mybatis-Generator 自动生成Dao、Model、Mapping相关文档

    最近在学习mybatis,结果在写Mapping的映射文件时insert语句一直报错,于是想看看标准的映射文件是什么样.百度到Mybatis-Generator 自动生成Dao.Model.Mappi ...

  6. sqoop1.99.4安装与简介

    1.什么是sqoop clouder公司开发的一个在关系数据库和hdfs,hive之间数据导入导出的一个工具 2.版本及其区别 现在分为sqoop1和sqoop2 1)架构图(sqoop1和hadoo ...

  7. 完整HttpHelper类

    [代码] [C#]代码 using System; using System.Collections.Generic; using System.Text; using System.Net; usi ...

  8. WPF 之 布局(三)

    六.DockPanel DockPanel定义一个区域,在此区域中,您可以使子元素通过描点的形式排列,这些对象位于 Children 属性中.停靠面板其实就是在WinForm类似于Dock属性的元 素 ...

  9. javaEE学习笔记-单例模式

    定义: 确保一个类只有一个实例,而且自行实例化并向整个系统提供这个实例. 单例模式的三要素: (1)私有的静态的成员变量 (2)私有的构造方法 (3)公共的静态的入口点方法 单例模式的分类: (1)饿 ...

  10. 设置eclipse在linux下提示

    在Windows下eclipse按alt+/就可以提示,但是在Linux下eclipse的设置不是这样的alt+/为切换输入法,如果要修改于Windows下的一样就需要修改一下快捷键: 点击windo ...