在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
测试实例如下: 前台代码MyFirstWeb.aspx(没有服务器控件,即没有runat)
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="MyFirstWeb.aspx.cs" Inherits="SimpleWeb.MyFirstWeb" %> <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title></title> </head> <body> <!--获取前台页面的程序集位置--> <%=this.GetType().Assembly.Location %> <form id="form1"> <div> <input type="text" name="txtName"/> <input type="submit" id="btnClick"/> </div> </form> </body> </html> 后台代码 using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; namespace SimpleWeb { public partial class MyFirstWeb : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { Response.Write("Page_Load方法的开始<br/>"); Response.Write("Page_Load方法的结束<br/>"); } } } 一个前台页面文件,在第一次被访问时,会被编译成一个类 前台页面会被编译成前台页面类myfirstweb_aspx,继承于后台页面类MyFirstWeb.cs
public class myfirstweb_aspx : MyFirstWeb, IRequiresSessionState, IHttpHandler { // Fields private static object __fileDependencies; private static bool __initialized; private static MethodInfo __PageInspector_BeginRenderTracingMethod; private static MethodInfo __PageInspector_EndRenderTracingMethod; private static MethodInfo __PageInspector_SetTraceDataMethod; // Methods static myfirstweb_aspx(); [DebuggerNonUserCode] public myfirstweb_aspx(); [DebuggerNonUserCode] private HtmlHead __BuildControl__control2(); [DebuggerNonUserCode] private HtmlMeta __BuildControl__control3(); [DebuggerNonUserCode] private HtmlTitle __BuildControl__control4(); [DebuggerNonUserCode] private void __BuildControlTree(myfirstweb_aspx __ctrl); private void __PageInspector_BeginRenderTracing(object[] parameters); private void __PageInspector_EndRenderTracing(object[] parameters); private static MethodInfo __PageInspector_LoadHelper(string helperName); private void __PageInspector_SetTraceData(object[] parameters); private void __Render__control1(HtmlTextWriter __w, Control parameterContainer); [DebuggerNonUserCode] protected override void FrameworkInitialize(); [DebuggerNonUserCode] public override int GetTypeHashCode(); [DebuggerNonUserCode] public override void ProcessRequest(HttpContext context); // Properties protected HttpApplication ApplicationInstance { get; } protected DefaultProfile Profile { get; } } 后台页面类MyFirstWeb.cs,如下 public class MyFirstWeb : Page { // Fields protected HtmlForm form1; // Methods protected void Page_Load(object sender, EventArgs e) { base.Response.Write("Page_Load方法的开始<br/>"); base.Response.Write("Page_Load方法的结束<br/>"); } } -------------------------------------------------------------开始分析源码----------------------------------------------------------------------------------- 1.当在浏览框中输入Localhost:MyFirstWeb.aspx,按回车的时候, 在请求管道的第8个事件,创建了与请求名同名的页面类对象myfirstweb_aspx.cs, 然后将该页面类对象保存到HttpContext中的RemapHandler中。 接着在管道的第11个事件和12个事件之间,调用页面对象的PR方法, 因为前台页面类继承于后台类,而后台类有继承于Page类,所以实际调用的是Page类的PR方法。 private void ProcessRequest() { Thread currentThread = Thread.CurrentThread; CultureInfo currentCulture = currentThread.CurrentCulture; CultureInfo currentUICulture = currentThread.CurrentUICulture; try { this.ProcessRequest(true, true); } finally { this.RestoreCultures(currentThread, currentCulture, currentUICulture); } } 1.1继续调用它的重载函数的PR方法
private void ProcessRequest(bool includeStagesBeforeAsyncPoint, bool includeStagesAfterAsyncPoint) { if (includeStagesBeforeAsyncPoint) { this.FrameworkInitialize(); base.ControlState = ControlState.FrameworkInitialized; } bool flag = this.Context.WorkerRequest is IIS7WorkerRequest; try { try { if (this.IsTransacted) { this.ProcessRequestTransacted(); } else { this.ProcessRequestMain(includeStagesBeforeAsyncPoint, includeStagesAfterAsyncPoint); } if (includeStagesAfterAsyncPoint) { flag = false; this.ProcessRequestEndTrace(); } } catch (ThreadAbortException) { try { if (flag) { this.ProcessRequestEndTrace(); } } catch { } } finally { if (includeStagesAfterAsyncPoint) { this.ProcessRequestCleanup(); } } } catch { throw; } } 2.FI方法,代码如下
[DebuggerNonUserCode] protected override void FrameworkInitialize() { base.FrameworkInitialize(); this.__BuildControlTree(this); base.AddWrappedFileDependencies(__fileDependencies); base.Request.ValidateInput(); } 2.1.__BuildControlTree()代码如下
[DebuggerNonUserCode] private void __BuildControlTree(myfirstweb_aspx __ctrl) { this.InitializeCulture(); HtmlHead __ctrl1 = this.__BuildControl__control2(); IParserAccessor __parser = __ctrl; __parser.AddParsedSubObject(__ctrl1); __ctrl.SetRenderMethodDelegate(new RenderMethod(this.__Render__control1)); } 2.1.1.__BuildControl__control2();代码如下
[DebuggerNonUserCode] private HtmlHead __BuildControl__control2() { HtmlHead __ctrl = new HtmlHead("head"); HtmlMeta __ctrl1 = this.__BuildControl__control3(); IParserAccessor __parser = __ctrl; __parser.AddParsedSubObject(__ctrl1); HtmlTitle __ctrl2 = this.__BuildControl__control4(); __parser.AddParsedSubObject(__ctrl2); object[] CS$0$0001 = new object[5]; CS$0$0001[0] = __ctrl; CS$0$0001[2] = 180; CS$0$0001[3] = 0x79; CS$0$0001[4] = false; this.__PageInspector_SetTraceData(CS$0$0001); return __ctrl; } 2.1.2.SetRenderMethodDelegate(new RenderMethod());调用一个委托,RenderMethod代码如下
private void __Render__control1(HtmlTextWriter __w, Control parameterContainer) { this.__PageInspector_BeginRenderTracing(new object[] { __w, "/MyFirstWeb.aspx", 0x70, 0x44, true }); __w.Write("\r\n\r\n<!DOCTYPE html>\r\n\r\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\r\n"); this.__PageInspector_EndRenderTracing(new object[] { __w }); parameterContainer.Controls[0].RenderControl(__w); this.__PageInspector_BeginRenderTracing(new object[] { __w, "/MyFirstWeb.aspx", 0x12d, 0x27, true }); __w.Write("\r\n<body>\r\n <!--获取前台页面的程序集位置-->\r\n "); this.__PageInspector_EndRenderTracing(new object[] { __w }); this.__PageInspector_BeginRenderTracing(new object[] { __w, "/MyFirstWeb.aspx", 340, 0x26, false }); __w.Write(base.GetType().Assembly.Location); this.__PageInspector_EndRenderTracing(new object[] { __w }); this.__PageInspector_BeginRenderTracing(new object[] { __w, "/MyFirstWeb.aspx", 0x17a, 0xa7, true }); __w.Write("\r\n <form id=\"form1\" >\r\n <div>\r\n <input type=\"text\" name=\"txtName\"/>\r\n <input type=\"submit\" id=\"btnClick\"/>\r\n </div>\r\n </form>\r\n</body>\r\n</html>\r\n"); this.__PageInspector_EndRenderTracing(new object[] { __w }); } ---------------------------------------------------------------问题解答-------------------------------------------------------------------------------------- 问题一:_ctrl1是什么类型?还有它被添加到前台页面类的哪个成员中? _ctrl1是前台页面类型,那么前台页面又是什么类型
那么一切问题都解决了,通过创建控件树,创建了一个个控件,同时将这些控件依次添加到前台页面的控件集合中,然后依次调用控件的RenderControl方法,将结果添加到字符数组中,然后将字符数组输出给HttpRuntime,然后传给iis,最后返回给浏览器,浏览器在根据接收到的结果,渲染界面,这就是我们最终看到的。 源码如下,就是按照字符数组中先后添加的代码显示到界面。为什么Page_Load中的数据先输出,请看超链接,文章后续会发布 Page_Load方法的开始<br/>Page_Load方法的结束<br/> <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><title> </title></head> <body> <!--获取前台页面的程序集位置--> D:\Users\Kimisme\AppData\Local\Temp\Temporary ASP.NET Files\root\5f14d39c\6593da16\App_Web_4br2rhb1.dll <form id="form1" > <div> <input type="text" name="txtName"/> <input type="submit" id="btnClick"/> </div> </form> <!-- Visual Studio Browser Link --> <script type="application/json" id="__browserLink_initializationData"> {"appName":"InternetExplorer","requestId":"6cd255e00ebe439facbd972bb23ed352"} </script> <script type="text/javascript" src="http://localhost:1090/86ceaccf0cf9404491a3a03bf9ab677a/browserLink" async="async"></script> <!-- End Browser Link --> </body> </html> |
请发表评论