20110612 DiscuzNT代码研究(3)
1. 说明本文主要讨论
1) ASP.NET的页面隐藏模型
2) 通过页面隐藏模型重写Discuz.Web-install-index.aspx页面
2. Asp.Net页面隐藏模式 2.1. 创建index_cfq.aspx的Web窗体页面选择install文件夹à右键à选择“添加-新建项”à选择“Web窗体”,输入“index_cfq.aspx”
2.2. index_cfq.aspx页面代码我们主要关注第1行,第一行说明:
1) 本页面采用的语言“C#”
2) 本页面的事件采用自动匹配:AutoEvenWireUp=”True”
3) 本页面采用代码隐藏模型:CodeBehind=”index_cfq.asp.cs”
4) 本页面编译时生成的类将继承Discuz.Web.install.index_cfq
2.3. @Page指令的AutoEvenWireUp属性AutoEvenWireUp属性用于指示“页面的事件是否自动匹配”。
当AutoEvenWireUp=true时,表示页面启动事件自动匹配。
2.3.1. 事件类型这里我们谈到事件,我们把事件适当区分一下:
1) 页事件:即Page页面的事件
2) 控件事件:即控件上的事件,比如aspx页面上有个Button控件,那么Button控件的事件成为控件事件。
AutoEvenWireUp是针对页事件而言的。
2.3.2. 事件与方法的绑定事件与事件处理方法的绑定,在.NET中是通过“委托”实现的,在ASP.NET中,有几种方式可以绑定事件方法。
1) 委托:在C#代码中实现
this.button1.Click += new System.EventHandler(this.button1_Click); |
2) 控件标记
<asp:Button ID="Button1" runat="server" onclick="Button1_Click" Text="Button" /> |
3) 基于方法命名约定的方法
一般指页事件的方法,这种绑定需要设置AutoEvenWireUp=true,其他地方不用指定方法与事件的关联,系统会自动查找按照“命名约定的方法”(Page_事件名称),然后即可启动事件。当然方法的参数必须与事件委托一致。
protected void Page_Load(object sender, EventArgs e) |
先看看下图,当然下图不是标准的UML图,只是为了解释一下而已。
本图是在页面隐藏模型下在Web服务器编译后的类图信息。
可以通过VS的类视图可以看得比较清楚
我们对整个过程稍微介绍一下。
当我们建立一个index_cfq的web窗体,VS自动帮忙创建了几个文件:
1) index_cfq.aspx
2) index_cfq.aspx.cs(index_cfq.aspx.designer.cs)
n index_cfq.aspx
主要是aspx页面信息,可以包括C#代码,服务器控件信息,HTML标记,CSS,JavaScript等等内容。
n index_cfq.aspx.cs(index_cfq.aspx.designer.cs)
index_cfq.aspx.cs主要放一些C#源代码,一般是一些方法,当然还可以有很多内容弄个,但是不包含aspx页面上的服务器控件定义信息(在index_cfq.aspx.designer.cs定义)。
其中index_cfq.aspx.designer.cs主要是放一些服务器控件的定义内容。
其中index_cfq.aspx文件编译后,实际上会产生两个类,一个是index_cfq的部分类,与index_cfq.aspx.cs文件编译后产生的index_cfq部分类一起构成index_cfq完整类。
同时index_cfq.aspx还产生一个类,即index_cfq_aspx类,此类继承自index_cfq类,这也是
中指定 Inherites="Discuz.Web.install.index_cfq"继承的意思。
如果把Inherites="Discuz.Web.install.index_cfq"改为
Inherites="Discuz.Web.install.index_cfq_cfq",则在运行时会提示如下错误:
然后观察类视图,即会发现,实际上系统仍自动创建一个index_cfq_cfq的类,只是这个类因为在其他页面没有指定继承Page,所以默认继承Object,但是对于ASP.NET页面必须继承Page,所以在运行提示错误,说明该类型不是继承与Page的错误。
然后我们Inherites="Discuz.Web.install.index_cfq"该回来,
然后把CodeBehind="index_cfq.aspx.cs"删除或者改为
CodeBehind="index_cfq_cfq.aspx.cs"
浏览程序,这是我们发现程序正常运行。
也就是说,实际上当我们编译了dll文件了,实际上我们可以不用CodeBehind这个东西,我们直接用Inherites指名我们要继承的类即可。
我再做一个实验。
1) 把“index_cfq.aspx.cs”改名为“index_cfq_cfq.aspx.cs”
2) 把“index_cfq.aspx.designer.cs”改名为“index_cfq_cfq.aspx.designer.cs”
这是会发现以下现象:
1) index_cfq_cfq.aspx.designer.cs自动关联到index_cfq_cfq.aspx.cs。这个应该是VS的机制。
2) index_cfq.aspx底下的两个文件会感叹号,可以删除了,所以下面图看不到。
之所有有感叹号,是因为在项目中有包含此两个文件,但是实际文件已经不存在了,所以提示感叹号。
然后选择那两文件,包含到项目中。
然后重新生成网站,运行index_cfq.aspx,正常!
这里需要注意两个细节: 1) 如果以上两文件为包含到项目中,则无法正常运行,会提示类不存在。 2) 如果未包含文件,但是通过CodeFile指定CS文件,也是可以运行的,但是发布网站时,必须一同发布源代码哦!(用CodeBehind也是不行的) |
既然我们立即了页面隐藏模式的原理,我们现在尝试把index.aspx页面修改为页面隐藏模式。
1) 建立一个index.aspx.cs文件,在其中创建一个index的类
2) 然后把<script></script>的代码搬移过来(可以不删除index中的代码,注释掉即可)。
3) 在index.aspx.cs文件的Page指令中添加如下内容:
4) 注释掉“Page_Lode”方法中的页面跳转代码,以便测试
5) 经过测试,调试成功。
(本文结束)