再学习Webform页面生命周期
参考文章:
在vs2010,新建一个aspx页面,页面头部有一行代码:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Index2.aspx.cs" Inherits="testWebForm.Index2" %>
Page Language="C#" 是指出页面编写语言为c#,这个可能是给页面解析引擎(非官方称呼自己理解)看的吧。
AutoEventWireup="true" 这个属性设置为true,会给页面的服务器控件事件,自动添加事件绑定代码(有vs开发工具生成,程序不理解,控件的事件也可以正常执行)。
CodeBehind="Index2.aspx.cs" 这个是指,页面后置类是哪一个类,asp.net webform有一个打特点就是代码后置,解决页面多种代码(html,css,js,C#,asp语法)写在一个页面,asp页面代码乱的问题。
Inherits="testWebForm.Index2" 单词Inherits是继承的意思,也就是说在服务器页面解析引擎执行时,将会把页面解析为testWebForm.Index2的一部分(有可能是子类或者是一个类也说不定,这只是我的理解,具体需要研究确认),总之这个代码后置属性与继承属性的标出,都是为了将来解析引擎能理解cs文件和aspx文件,并进行解析执行服务的。
补充:从编程经验来看,我们可以在aspx页面访问到后台的属性以及public、protected修饰的字段,所以解析引擎有可能把aspx页与cs、designer解析成了一个类。 cs文件和designer.cs文件本身都是属于一个类,这里用了部分类关键字 partial。
现在来想一个问题,为什么有页面生命周期呢?
因为客户端请求http://192.169.1.100:8080/index.aspx页面,服务器不是直接去读取index.aspx文件,然后返回的。
这里大概流程:首先要找到aspx页面,然后根据页面的头部标识(上面已经说明),在dll代码中找到它的另外一部分(cs代码部分,这部分发布网站时,都被编译成了dll文件)然后根据designer.cs中的属性(这部分是当时你往页面拖放控件时,vs自动帮你生成的代码)一个一个去aspx页面找到对应的html部分如:
designer.cs中生成的一个属性:
/// <summary>
/// Label1 控件。
/// </summary>
/// <remarks>
/// 自动生成的字段。
/// 若要进行修改,请将字段声明从设计器文件移到代码隐藏文件。
/// </remarks>
protected global::System.Web.UI.WebControls.Label Label1;
在aspx页面有一个asp.net服务器控件与之对应:
<asp:Label ID="Label1" runat="server" Text="Label" ViewStateMode="Disabled"></asp:Label>
然后属性Label1是Label 类型的,这个Label类有很多属性:
namespace System.Web.UI.WebControls { // 摘要: // 表示在网页上显示文本的标签控件。 [ControlValueProperty("Text")] [ControlBuilder(typeof(LabelControlBuilder))] [ParseChildren(false)] [DataBindingHandler("System.Web.UI.Design.TextDataBindingHandler, System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")] [Designer("System.Web.UI.Design.WebControls.LabelDesigner, System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")] [ToolboxData(@"<{0}:Label runat=""server"" Text=""Label""></{0}:Label>")] [DefaultProperty("Text")] public class Label : WebControl, ITextControl { // 摘要: // 初始化 System.Web.UI.WebControls.Label 类的新实例。 [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] public Label(); // 摘要: // 获取或设置 System.Web.UI.WebControls.Label 控件关联的服务器控件的标识符。 // // 返回结果: // 一个字符串,对应于 Web 窗体中包含的服务器控件的 System.Web.UI.Control.ID。默认值为空字符串 (""),指示 System.Web.UI.WebControls.Label // 控件不与其他服务器控件相关联。 [TypeConverter(typeof(AssociatedControlConverter))] [IDReferenceProperty] [DefaultValue("")] [WebCategory("Accessibility")] [WebSysDescription("Label_AssociatedControlID")] [Themeable(false)] public virtual string AssociatedControlID { get; set; } // // 摘要: // 获取一个值,该值指示在控件的 System.Web.UI.WebControls.WebControl.IsEnabled 属性为 false 时,控件是否应将呈现的 // HTML 元素的 disabled 特性设置为“disabled”。 // // 返回结果: // 如果 System.Web.UI.Control.RenderingCompatibility 属性指示 ASP.NET 版本低于 4.0,则为 // true;否则为 false。 public override bool SupportsDisabledAttribute { get; } // // 摘要: // 获取用于呈现 System.Web.UI.WebControls.Label 控件的 HTML 标记。 // // 返回结果: // 用于呈现 System.Web.UI.WebControls.Label 的 System.Web.UI.HtmlTextWriterTag 值。 protected override HtmlTextWriterTag TagKey { get; } // // 摘要: // 获取或设置 System.Web.UI.WebControls.Label 控件的文本内容。 // // 返回结果: // 控件的文本内容。默认值为 System.String.Empty。 [Bindable(true)] [Localizable(true)] [WebCategory("Appearance")] [DefaultValue("")] [WebSysDescription("Label_Text")] [PersistenceMode(PersistenceMode.InnerDefaultProperty)] public virtual string Text { get; set; } // 摘要: // 添加要呈现到指定输出流的 System.Web.UI.WebControls.Label 控件的 HTML 属性和样式。 // // 参数: // writer: // System.Web.UI.HtmlTextWriter,表示要在客户端呈现 HTML 内容的输出流。 // // 异常: // System.Web.HttpException: // 未能找到 System.Web.UI.WebControls.Label.AssociatedControlID 属性中指定的控件。 protected override void AddAttributesToRender(HtmlTextWriter writer); // // 摘要: // 通知控件某元素已经过分析,并将该元素添加到 System.Web.UI.WebControls.Label 控件。 // // 参数: // obj: // 表示已分析元素的对象。 protected override void AddParsedSubObject(object obj); // // 摘要: // 加载以前保存的控件的状态。 // // 参数: // savedState: // 包含控件的已保存视图状态值的对象。 protected override void LoadViewState(object savedState); // // 摘要: // 将 System.Web.UI.WebControls.Label 的内容呈现到指定的编写器中。 // // 参数: // writer: // 向客户端呈现 HTML 内容的输出流。 protected internal override void RenderContents(HtmlTextWriter writer); } }
以上是我复制的Label类的代码。你在aspx页为控件属性赋的值,会在解析后赋值给Label类的属性。上面我们说到aspx页面的asp.net服务器控件,与designer.cs的属性都是一一对应的,在页面解析引擎执行时,都会被对比解析。然而这说明了什么呢?
这是为了说明什么?aspx页面之所以有生命周期,是因为要做这些解析,其实其他页面也都有生命周期不过他们很短。
如果我们aspx页面不用服务器控件,也就会少了这一步解析,没有这一步解析页面就与普通的asp或者php的编程模型很类似了。
即使没有了服务器控件,但是不代表页面不需要解析,我们页面写的给页面的不同地方如<h2><%=title%></h2>这个给页面绑定标题的这种标签语法,还有其他各种绑定代码都是需要解析执行的。这就是为什么把webform叫做动态服务页面的原因吧。
需要明确的是:在<%%>中写代码和在cs文件中没有本质区别,它们是一样的,只不过<%%>可以灵活的控制将来生成的html页面,不同地方显示不同内容。
参考资料:网络上其他很多博客