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

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. 窗口界面编程之一:VB实现简单异形窗口

    一.运行效果图(在Win8里的运行效果,在XP里运行就不能体现出来,因为我使用的XP的界面效果) 二.编译环境:Visual Basic 6.0 (SP6) 三.实现原理:通过区域合并 四.使用API ...

  2. CSS样式如何解决IE浏览器不同版本的兼容问题

    如果你想让浏览器是固定的IE6版本,那么你做网页的时候在<head>后面加上一句话: <meta http-equiv="X-UA-Compatible" con ...

  3. Android端百度地图API使用详解

    百度地图API简介 百度地图移动版API(Android)是一套基于Android设备的应用程序接口,通过该接口,可以轻松的访问百度服务和数据,构建功能丰富.交互性强的地图应用程序. 百度地图移动版A ...

  4. Eclipse中R文件不能自动生成

       R文件不能自动生成主要是因为编译有错误,这时你想什么办法都是没有用的,clean, fix properties,都不是从根上解决问题.    R文件主要是自动生成资源文件的id的,里边静态子类 ...

  5. 剑指 offer set 1 二维数组中查找

    总结 1. 二维数组搜索题遇到两个了, 一个是 Leetcode 上 search in 2D matrix. 那道题比较简单, 因为下一行的所有元素大于上一行的. 这道题对二维矩阵的要求比较松, 起 ...

  6. c#使用MethodInvoker解决跨线程访问控件

      功能函数测试集锦(77)  C#专区(114)  版权声明:本文为博主原创文章,未经博主允许不得转载. .net 原则上禁止跨线程访问控件,因为这样可能造成错误的发生,有一种方法是禁止编译器对跨线 ...

  7. [Buzz.Today]2013.07.26

    # OpenFab 3D printing hardware is rapidly scaling up to output continuous mixtures of multiple mater ...

  8. WinForm实现跨进程通信的方法

    public class WinMessageHelper { private struct COPYDATASTRUCT { public IntPtr dwData; public int cbD ...

  9. 顺丰快递单号查询api对接(全代码)

    接口支持的消息接收方式:HTTP POST 请求方法的编码格式(utf-8):"application/x-www-form-urlencoded;charset=utf-8" 请 ...

  10. C. Ilya and Sticks

    C. Ilya and Sticks time limit per test 2 seconds memory limit per test 256 megabytes input standard ...