20110611 DiscuzNT代码研究(二)- Discuz.Web-install-index.aspx

pdf下载:http://download.csdn.net/source/3357916

1. 说明

1) 本文分析将按照每个项目进行分析,每个项目建立文件大纲进行分析,同时会引申一些相关的内容知识。

本节分析文件:

Discuz.Web\install\index.aspx

2) 本节对部分内容会进行详细说明,以后章节将不再重复。

3) 本文不保证所有的用语都是标准的,如有语误,或者打错字,欢迎指正,可发邮件给我:cfqlilei@139.com(务必说明你是谁哦,算是认识一下,呵呵)

4) 有兴趣可关注本人博客:

CSDN: http://blog.csdn.net/cfqlilei

博客园: http://www.cnblogs.com/wesoft/

51CTO: http://cfqlilei.blog.51cto.com/

2. index.aspx 2.1. 代码分析方法

1) 截图

2) 分析类成员(UML)

3) 分析类成员的实现和作用(深入源代码)

2.2. 截图

clip_p_w_picpath002

2.3. 分析类

从代码的前段,可以看出index.aspx页面没有相应的cs文件,本页面将在被浏览器请求的时候,自动编译一个继承与Page类的页面出来。

为了好分析,我们假设生成的类为index.aspx类

index.aspx的第一行,置顶了本页面的编译语言为C#

<%@ Page Language="C#"%>

index.aspx的C#代码是在<script runat="server">…</script>体现出来。

2.4. 分析类成员

我们为_Index_Page类画一个UML图,借助“EnterpriseArchitect”工具,非常不错的一个UML建模工具。

clip_p_w_picpath004

从UML类图中可以看出,index.aspx基本上就是一个Page_Load方法,两个字段,这个方法和字段主要做什么作用呢?

2.5. 字段 2.5.1. httpModuleTip

提前说明:因为在源代码中加入注释等原因,截图中的行号与实际源代码的行号可能不一致。

该字符串主要是为了做“模块提示”信息

clip_p_w_picpath006

如果在web.config文件中不存在相应的节点,则提示相应信息。

clip_p_w_picpath008

我们稍微修改一下判断代码,即可看到提示效果,修改位置如下:

clip_p_w_picpath010

由于在判断条件中,都是用来“或”,随便改一个地方,判断条件不成立,就体会提示信息,提示信息放在哪里呢?

clip_p_w_picpath012

运行效果如下:

clip_p_w_picpath014

2.5.2. Msg

从对httpModuleTip的分析,我们看出,最终要显示在页面的信息就是通过Msg来显示出来。

显示方法有两种:

方法一:<%=msg%>

方法二:<%Response.Write(msg);%>

以上两种方法只能嵌入在Html标记中。

2.6. 方法 2.6.1. Page_Load

如何来分析Page_Load方法,实际上应该是事件方法,这个方法主要解决什么问题呢?

为了调试某个方法具体作用,有些时候我们需要在方法中添加一些测试方法,看看里面到底做些什么事情。

clip_p_w_picpath016

比如我们添加了一个测试方法“Response.Write(binfolderpath);”,并注释后续的代码,我们的目的是要只要HttpRuntime.BinDirectory返回的是什么样的值,返回结果值如下:

G:\WebServer\DiscuzNt360\source_files\Discuz.Web\bin\

即HttpRuntime.BinDirectory返回的是当前应用程序的 /bin 目录的路径。

2.6.1.1. 变量分析

我们先分析一下方法中的一些变量。

为了便于分析,我们把方法中涉及到的一些变量先浏览一遍。

clip_p_w_picpath018

2.6.1.1.1. bool isAssemblyInexistence

用于标识程序集是否存在

clip_p_w_picpath020

2.6.1.1.2. string binfolderpath = HttpRuntime.BinDirectory;

用于存储bin文件夹目录

binfolderpath=G:\WebServer\DiscuzNt360\source_files\Discuz.Web\bin\

2.6.1.1.3. string[] assemblylist = new string[] { "Discuz.Aggregation.dll"…};

用于存储程序集名称,由于涉及多个程序集,所以要存储多个字符串信息,这里采用字符串数组存储。

clip_p_w_picpath022

2.6.1.1.4. ArrayList inexistenceAssemblyList = new ArrayList();

用于存储“不存在的程序集名称”,假如“Discuz.Aggregation.dll”不存在,则该字符串会被存储在inexistenceAssemblyList中。 clip_p_w_picpath024

2.6.1.1.5. string xPath1 = "/configuration/system.web/httpModules";

用于存储一个xPath字符串,该字符串将被用于在XML查找相应的节点,如以上初始化"/configuration/system.web/httpModules",可以被用于检索如下类型的XML节点。

<configuration>

<system.web>

<httpModules>

</httpModules>

</system.web>

</configuration>

本节中,用于检索web.config文件中的节点信息,我们看看web.config文件

clip_p_w_picpath026

2.6.1.1.6. System.Xml.XmlDocument webConfig = new System.Xml.XmlDocument();

创建一个XML对象,以便对XML进行操作,如何指定要操作的XML文件呢?就是要指定文件路径即可。

用XmlDocument对象的Load方法即可,代码如下:

clip_p_w_picpath028

这里指定了要操作的XML路径为:应用程序目录下的web.config。

如果获取应用程序目录,采用binfolderpath.Replace("bin\\","")方法,该方法把“bin\”替换为空,即

binfolderpath=G:\WebServer\DiscuzNt360\source_files\Discuz.Web\bin\

替换后效果:

binfolderpath=G:\WebServer\DiscuzNt360\source_files\Discuz.Web\

于是web.config路径为

binfolderpath=G:\WebServer\DiscuzNt360\source_files\Discuz.Web\web.config

clip_p_w_picpath030

2.6.1.1.7. System.Xml.XmlNode node1 = webConfig.SelectSingleNode(xPath1);

用于代表一个XML的节点,通过XmlNode对象,可以获取该节点和子节点的所有信息。

这里主要是要返回web.config文件中

<configuration>

<system.web>

<httpModules>

(这里的第一个节点)

</httpModules>

</system.web>

</configuration>

即:

clip_p_w_picpath032

如何获取一个XML文件中节点的对象,可以采用如下方法,我们通过VS的帮助文件一下XmlDocument对象的信息。

我们发现XmlDocument有以下几个方法:

clip_p_w_picpath034

通过以上方法,可以获取:

1) 满足查询条件的节点列表,比如SelectNodes方法返回XmlNodeList对象。

2) 满足查询条件的第一个节点,比如SelectSingleNode方法返回XmlNode对象。

2.6.1.2. 方法主要功能

分析了主要字段后,我们在回头看看整体。

该方法主要做以下工作:

1) 检验dll文件在bin文件夹中是否存在

2) 检验web.config中是否存在需要的节点信息

3) 如果检验不通过,则提示相应信息,以便调整

4) 如果检验通过,则跳转到install.asp页面

2.6.1.3. 方法实现关键点

1) 通过assemblylist来存储需要检验的dll程序集信息

clip_p_w_picpath036

学习点:

l 如何初始化数组

2) 然后遍历assemblylist中的信息,检查文件是否存在,如果不存在,则设置isAssemblyInexistence为true(表示dll文件不存在),并且在inexistenceAssemblyList中增加相应的dll文件名称,那么通过inexistenceAssemblyList可以知道哪些dll文件是不存在的。

clip_p_w_picpath038

学习点:

l 如何创建数据列表:new ArraryList()

l 如何为数组列表添加元素:Add方法

l 如何判断文件是否存在:System.IO.File.Exists(路径)

l 如何获取文件路径:HttpRuntime.BinDirectory+“Discusz.Cache.dll”

l 如何变量数组:foreach的使用

3) 如果dll文件部分或者全部不存在(isAssemblyInexistence为true),那么就遍历inexistenceAssemblyList,列出哪些dll文件不存在。

clip_p_w_picpath040

学习点:

l <li>:Html标记,可显示列表

4) 然后在检查web.config文件中是否存在“/configuration/system.web/httpModules”和“/configuration/system.webServer/modules”节点信息,主要是为了保证将来的使用。

这里分为几个步骤:

a) 先判断web.config文件是否存在:System.IO.File.Exists

b) 先获取Xml对象:System.Xml.XmlDocument对象,Load方法

c) 再获取node对象: XmlDocument对象的SelectSingleNod方法

d) 然后判断node是否正常,以此来检验

clip_p_w_picpath042

实现分析:

在判断节点是否ok,这里用如“node1==null”,为什么要这么用呢?主要是为了提高效率,因为当“node1==null”的话,后续的判断条件就不用校验了,效率就高了。

node1.ChildNodes.Count <= 0,也是同样原理。

学习点:

l 如何获取XML对象:System.Xml.XmlDocument对象,Load方法

l 如何获取Node对象:XmlDocument对象的SelectSingleNod方法

l 如何判断节点是否存在:

node1 == null || node1.ChildNodes.Count &lt;= 0 || node1.InnerXml.IndexOf("Discuz.Forum.HttpModule") &lt; 0

5) 如果不存在,则同样提示信息,不过这里就不像dll文件那样提示搞得那么复杂,就直接httpModuleTip字符串信息提示就过去了,知道就行了。

6) 当检验都通过的话,那么isAssemblyInexistence就为false,这是就跳转到install.aspx。

clip_p_w_picpath044

学习点:

l 如何跳转页面:Respone.Redirect(页面地址)

2.7. 补充知识点

1) HttpUtility.HtmlEncode

将字符串转换为 HTML 编码的字符串,比如当字符串中包含特殊字符,如“&lt;>,/,\”等等,如果我们希望完整通过HTML显示的话,就要用HttpUtility.HtmlEncode。

2) System.Xml.XmlNode node1 = webConfig.SelectSingleNode(xPath1);

XmlNode.SelectSingleNode 方法

选择匹配 XPath 表达式的第一个 XmlNode

XmlNode对象对应一个XML的节点(元素)

XmlNode 类在System.Xml(在 System.Xml.dll 中)命名空间中

3) Response.Write("<br>" + HttpUtility.HtmlEncode(node1.InnerXml));

node1.InnerXml表示获取node1节点中的内部Xml,包含了内部节点的信息

clip_p_w_picpath046

如果用node1.InnerText,只是显示该节点和子节点的标记文本(子节点文本)。

如果用node1.OuterXml,则显示该节点和子节点的标记(本节点+子节点)。

如果用node1.InnerXml,则只是显示子节点的标记(子节点)。

clip_p_w_picpath048

4) Response.Write("<br>" +node1.InnerXml);

5) Response.Write("<br>" + node1.InnerXml.IndexOf("Discuz.Forum.HttpModule").ToString());

2.8. XML学习(XML的结构)

从下图可以看出,XML由以下几个元素组成:

1) 元素(根元素、子元素):XmlNode对象

2) 属性:

用XmlNode. Attributes可以获取到属性列表(XmlAttributeCollection),可以通过XmlAttributeCollection. XmlAttribute (string)方法获取置顶属性的值。

3) 文本

用Xml.Node. OuterXml可以获取该节点和子节点的标记

用Xml.Node. InnerText可以获取或设置该节点和子节点的标记

用Xml.Node.Value,不同NodeType返回的Value不一致

clip_p_w_picpath050

clip_p_w_picpath052

(本节完毕)