主题机制使得开发人员可以很轻松地对页面的设置实现更多的选择。它在处理主题的设置时提供了清晰的目录结构,提供了良好的扩展性。因此使用主题可以提高设计和维护网站的效率。
主题是有关页面和控件的外观属性设置的集合,由一组元素组成,包括外观文件、级联样式表(CSS)、图像和其他资源。
主题至少包含外观文件(.skin文件),主题是在网站或Web服务器上的特殊目录中定义的,一般把这个特殊目录称为专用目录,目录的名字为App_Themes。App_Themes目录下可以包含多个主题目录,主题目录的命名由程序员决定。而外观文件等资源则是放在主题目录下的。
主题的组成元素
1.外观文件
外观文件又称皮肤文件,是具有文件扩展名.skin的文件,在皮肤文件里,可以定义控件的外观属性。
外观文件形式一般具有下面形式:
<asp:Label runat="serve BackColor="Blue"></asp:Label>
上面定义了Label控件的一个皮肤,可以在网页引用该皮肤去设置Label控件的外观。
2.级联样式表
级联样式表就是CSS文件,是具有文件扩展名.css的文件,也是用来存放定义控件外观属性的代码的文件。
3.图像和其他资源
图像就是图形文件,其他资源可能是声音文件、脚本文件等。有时候为了控件美观,只是靠颜色、大小和轮廓来定义并不能满足要求,这时候就会考虑把一些图片、声音等加到控件外观属性定义中去。
主题的分类
主题按照应用范围可分为页面主题和全局主题。
页面主题应用于单个Web应用程序它是一个位于App_Themes文件夹下的主题文件夹,包含控件外观、样式表、图形文件和其他资源。
全局主题可应用于服务器上的所有网站,全局主题和页面主题类似,全局主题存储在Themes文件夹中,服务器上的任何网站以及任何网站中的任何页面都可以引用全局主题。
主题的特性
1.主题只在ASP.NET控件中有效。
2.母版页上不能设置主题,但主题可以在内容页面上设置。
3.主题上设置的ASP.NET控件的样式覆盖页面上设置的样式。
4.如果在页面上设置EnableTheming="false",则主题无效。
5.在页面中动态设置主题,必须在页面生命周期Page_Preinit事件之前进行设置。
6.主题包括.skin和.css。
使用主题时可能会引起安全问题
1.改变控件的行为,导致有异于预期的行为。
2.插入客户端脚本,导致跨站点式脚本风险。
3.改变验证。
4.公开敏感信息。
缓解措施
1.使用正确的访问控制设置来保护全局和应用程序的主题目录,应只允许受信任的用户将文件写入主题目录中。
2.不要使用来自不受信任的主题,若要在网站上使用来自单位外部的主题,应先检查是否包含恶意代码。
3.不要在查询数据中公开主题名称,恶意用户可以通过此信息来使用开发人员不知道的主题,从而公开敏感信息。
主题的创建
1.右键单击要为之创建主题的网站项目,在弹出的菜单中选择“添加ASP.NET文件夹”|“主题”命令。此时就会在该网站项目下添加一个名为App_Themes文件夹,并在该文件夹中自动添加一个默认名为主题1的文件夹。
2. 右键单击主题1文件夹,在弹出的菜单里选择“添加”命令,弹出添加菜单,该菜单提供了在主题1文件夹里可以添加的文件的模板。
3. 选择新建项,在弹出对话框里选择“外观文件”,修改文件名为Skin1,单击“添加”,Skin1.skin就会添加在Themes1目录下。
主题的应用
在网页中使用某个主题,只需在网页定义中加上“Theme=[主题目录]”属性,示例代码如下:
<%@ Page Theme="主题1"%>
通过把属性Themes设置为Themes1来把该主题应用于网页。
为了将主题应用于整个项目,可以项目的根目录下的Web.config文件里进行配置,示例代码如下:
1 <configuration> 2 <system.web> 3 <Pages Themes="主题1"></Pages> 4 </system.web> 5 </configuration>
SkinID的应用
SkinID是ASP.NET为Web控件提供的一个联系到皮肤的属性,用来标识控件使用哪种皮肤。有时需要同时为一种控件定义不同的显示风格,这时可以在皮肤文件中定义SkinID属性来区别不同的显示风格,例如,在LabelSkinFile1.skin文件中对Label控件定义了三种显示风格的皮肤,代码如下:
1 <asp:Label runat="server" BackColor="Red"></asp:Label> 2 <asp:Label runat="server" SkinID="Style2"BackColor="Pink"></asp:Label> 3 <asp:Label runat="server" SkinID="Style3" BackColor="Green"></asp:Label>
主题的禁用
当不希望主题重写页和控件外观的本地设置时,就可以利用禁用方法来禁用主题。禁用页的主题通过设置@Page指令的EnableTheming属性为false来实现,例如:
<%@ Page EnableTheming="false"%>
禁用控件的主题通过将控件的EnableTheming属性设置为false来实现,例如:
<asp:Calendar id="Calendar1" runat="server" EnableTheming="false" />
使用实例1:
在项目中新建App_Themes文件夹,添加主题1文件夹,并新建外观文件Skin1.skin,代码如下:
1 <asp:Label runat="server" BackColor="Green"/> 2 <asp:TextBox runat="server" BackColor="Pink"/> 3 <asp:Button runat="server" BackColor="White" ForeColor="Blue" Font-Italic="True" Font-Bold="true"/>
在Default.aspx中,在网页定义中添加Theme="主题1"属性,并添加如下代码:
1 <div> 2 <table> 3 <tr> 4 <td> 5 <asp:Label ID="Label1" runat="server" Text="用户名:" /> 6 </td> 7 <td> 8 <asp:TextBox ID="TextBox1" runat="server" /> 9 </td> 10 </tr> 11 <tr> 12 <td> 13 <asp:Label ID="Label2" runat="server" Text="密码:" /> 14 </td> 15 <td> 16 <asp:TextBox ID="TextBox2" runat="server" /> 17 </td> 18 </tr> 19 <tr> 20 <td> 21 <asp:Button ID="Button1" runat="server" Text="登录"/> 22 </td> 23 </tr> 24 </table> 25 </div>
使用实例2:
在项目中新建App_Themes文件夹,添加主题1文件夹,并新建外观文件Skin1.skin,代码如下:
1 <asp:Label runat="server" BackColor="Yellow"/> 2 <asp:TextBox runat="server" BackColor="Yellow"/> 3 <asp:Button runat="server" BackColor="White" ForeColor="Yellow" Font-Bold="true"/> 4 <asp:DropDownList runat="server" BackColor="Yellow"/>
添加主题2文件夹,并新建外观文件Skin2.skin,代码如下:
1 <asp:Label runat="server" BackColor="Pink"/> 2 <asp:TextBox runat="server" BackColor="Pink"/> 3 <asp:Button runat="server" BackColor="White" ForeColor="Pink" Font-Bold="true"/> 4 <asp:DropDownList runat="server" BackColor="Pink"/>
添加主题3文件夹,并新建外观文件Skin3.skin,代码如下:
1 <asp:Label runat="server" BackColor="Violet"/> 2 <asp:TextBox runat="server" BackColor="Violet"/> 3 <asp:Button runat="server" BackColor="White" ForeColor="Violet" Font-Bold="true"/> 4 <asp:DropDownList runat="server" BackColor="Violet"/>
在Default.aspx中,在网页定义中添加Theme="主题1"属性,并添加如下代码:
1 <div> 2 <table> 3 <tr> 4 <td> 5 <asp:Label ID="Label1" runat="server" Text="用户名:" /> 6 </td> 7 <td> 8 <asp:TextBox ID="TextBox1" runat="server" /> 9 </td> 10 </tr> 11 <tr> 12 <td> 13 <asp:Label ID="Label2" runat="server" Text="密码:" /> 14 </td> 15 <td> 16 <asp:TextBox ID="TextBox2" runat="server" /> 17 </td> 18 </tr> 19 <tr> 20 <td colspan="2"> 21 <asp:DropDownList ID="DropDownList1" runat="server" AutoPostBack="true"> 22 <asp:ListItem Value="主题1">黄色</asp:ListItem> 23 <asp:ListItem Value="主题2">粉色</asp:ListItem> 24 <asp:ListItem Value="主题3">紫色</asp:ListItem> 25 </asp:DropDownList> 26 </td> 27 </tr> 28 <tr> 29 <td colspan="2"> 30 <asp:Button ID="Button1" runat="server" Text="登录"/> 31 </td> 32 </tr> 33 </table> 34 </div>
在Default.aspx.cs中,添加Page_PreInit事件,设置当前的被选中主题(主题的设置必须在Page_Load事件之前)。
1 protected void Page_PreInit(object sender, System.EventArgs e) 2 { 3 if (IsPostBack) 4 { 5 Page.Theme = Request["DropDownList1"]; 6 } 7 }