主要讨论两个问题,
1.aspx页面为什么可以访问aspx.cs类的非私有成员?
2.aspx.cs类为什么可以通过this的方式访问前台的服务端控件?
按下面的步骤一步步揭晓答案
1.找到当前站点或应用程序执行的程序集 Response.Write(this.GetType().Assembly.Location);
2.主要通过Reflector反编译
1 public class default_aspx : _Default, IHttpHandler 2 { 3 // Fields 4 ... 5 6 // Methods 7 ... 8 private void __BuildControlTree(default_aspx __ctrl); 9 [DebuggerNonUserCode] 10 protected override void FrameworkInitialize(); 11 ... 12 public override void ProcessRequest(HttpContext context); 13 }
1>通过上面可以看到,aspx类继承了aspx.cs类和IHttpHandler接口,因为aspx页面类继承了aspx.cs类,所以在aspx页面可以访问aspx.cs类中非私有的成员
1 public class _Default : Page, IRequiresSessionState 2 { 3 // Fields 4 protected AdRotator AdRotator1; 5 protected Button Button1; 6 protected FileUpload FileUpload1; 7 protected HtmlForm form1; 8 9 // Methods 10 ... 11 // Properties 12 ... 13 }
2>当我aspx页面放一个服务端控件(等于在aspx页面类里面创建了对应控件类的一个对象并实例化),通过上面我们可以发现对应后台aspx.cs类也默认建了对应的受保护的控件类的对象字段,那它是怎么和前台aspx类的控件类实例关联起来的了?
1 private Button __BuildControlButton1() 2 { 3 Button button = new Button(); 4 base.Button1 = button; 5 button.ApplyStyleSheetSkin(this); 6 button.ID = "Button1"; 7 button.Text = "Button"; 8 return button; 9 }
3>aspx页面类的 BuildControlTree方法(通过这个方法来初始化控件树),在这个方法里面会调用BuildControlform1,在这个方法里会初始化所有Form表单里的控件
上面以Button为例, base.Button1 = button;这个语句就把后台的控件类对象字段和前台的控件实例关联起来。
补充:
具体是在哪里掉BuildControlTree的方法
当请求管道执行到第十一个到十二个事件执行第八个事件创建的页面对象的ProcessRequst方法,在这个方法里面为掉父类的ProcessRequest方法(Page类),在这个方法里面会调用其他一些方法,当调用到ProcessRequest方法(两个bool参数的重载),在这里会调用FrameworkInitialize方法,这个方法是虚方法已经被我们的aspx页面类重写,所有在这里调用的是aspx页面类的FrameworkIntialize方法,在它里面会调用BuildCotrolTree来初始化控件树
有兴趣的朋友可以通过Reflector来一步步跟着研究研究