024-母版页MasterPage

网站的布局通常是统一的,上面是Logo、菜单条、下面是公司地址、版权声明等。如果每个页面都重复做这些功能的话:重复性劳动、一旦修改那么每个页面都要修改。.Net中一般用母版(MasterPage)技术来解决这个问题。

MasterPage是这样一种技术,把页面布局画好,在变化的内容部分“留空”,留空的部分由子页面填充内容,这样子页面只要填空就行,不用重复设计页面结构,一旦要修改页面结构修改母版页就可以,这样所有页面都会变化。母版页“留空”,具体页面“填空”。母版页、具体页面中几乎可以使用所有的普通WebForm页面能够使用的技术。

添加一个“母版页”,使用<asp:ContentPlaceHolder>留空,新建的母版页已经自动设置了两个ContentPlaceHolder,还可以添加更多的ContentPlaceHolder。在id="head"前面后面都加入一些script,在id="ContentPlaceHolder1"前后也加入一些内容。
创建使用母版页的具体页面,WebSite是新建“Web窗体”的时候勾选“选择模板页”,WebApplication是新建“Web内容窗体”,然后选择页面使用的母版页(一个项目内可以创建多个母版页,比如新闻频道用一个母版页,视频频道用另外一个母版页)。
使用母版的具体页面和普通aspx页面的不同是:@Page区域用MasterPageFile属性表示页面使用哪个母版页,页面不包含html等内容,只定义了<asp:Content这些填坑的内容。<asp:Content>就是用来在具体页面中对母版页进行填坑的,ContentPlaceHolderID为这个Content要填母版页中的哪个坑,对应母版页中ContentPlaceHolder的Id

具体页面可以对母版页留空也可以不留空,如果不留空则显示<asp:ContentPlaceHolder>中定义的默认内容。
案例:实现上导航菜单、下版权声明,左侧功能面板,右侧为具体的内容的模板,然后分别实现关于我们和登录界面。
在母版页中使用超链接、图片地址等的时候需要注意路径问题,在母版页中的runat=server控件的链接地址、图片地址等会被解析为相对于母版页的地址,而客户端HTML控件ASP.Net引擎是直接输出的,因此是解析为相对于具体页面的地址。建议使用服务端控件,如果不能使用服务器控件,那么可以在aspx页面中调用ResolveClientUrl 、ResolveUrl进行虚拟路径的转换
每个具体页设置不同的标题,只要在具体页面的@page中设置Title属性即可。可以在具体页中通过Master.FindControl来定位母版页中的控件然后对母版页中的控件进行操作,比如在一个具体页面中将母版页中的一个控件隐藏。

HTML控件(错误):<img src="images/bjxz.png" width="100" height="100" />
runat=server的HTML控件:<img src="~/baodiao/images/bjxz.png" width="100" height="100" runat="server" />
服务端控件:<asp:Image ID="Image1" runat="server" ImageUrl="~/baodiao/images/bjxz.png" />
ResolveClientUrl:<img src='<%=ResolveClientUrl("~/baodiao/images/bjxz.png") %>' width="100" height="100" />

1>新建一个母版页,介绍母版页的结构。
2>新建一个使用指定母版页的WebForm,说明在WebForm中如何使用母版页。
3>在子页面中获取母版页中的控件this.Master.FindControl("TextBox1");注意:应用了母版页的页面,并没有继承自母版页,而是在子页面中有一个Master属性包含母版页。
4>在子页面中设置Page的Title属性,改变每个不同子页面的Title
5>~/路径。
6>母版页中使用客户端控件时的路径问题。比如使用img标签。 <img src='<%=ResolveUrl("~/imgs/bg.png")%>' />.在母版页中如果出现服务器端控件,那么路径可以使用"~/",但如果是html控件,则不识别"~/",但也不能直接把路径写成相对于当前母版页的路径,那样的话再不同的应用母版页的页面中路径解析就有问题了,所以此时可以使用ResolveUrl("~/")

注意:
在母版页中当设置例如图片框,或者超链接等的路径的时候,要记住,不能直接相对于当前母版页与资源文件的路径来直接设置,
如果这样直接设置的话,可能将来应用该母版页的页面,所在的位置与当前母版页并不一致,所以可能造成路径不对的问题。

此时可以考虑使用 / 表示网站根目录,无论将来应用母版页的页面在任何地方,当在母版页中编写资源的路径的时候,始终从网站根目录开始查找 : /imgs/1.png 这样就可以避免出现相对于母版页写相对路径的问题。但是 / 表示的是网站的跟目录,如果当前的Web应用程序发布的时候不是发布到了根网站下,而是某个网站下的某个“子应用(“虚拟目录”)”,这时通过/查找的是网站根目录,而我们此时想要的是相对于当前Web应用的根目录:
例如:http://localhost:1307/WebSite41/Default.aspx

~/ 表示查找当前应用程序的根目录(查找的结果可能是当前网站的根目录,也可能不是,取决于如何部署当前web应用),
"~/ " 这种写法只有asp.net才能识别,例如asp.net服务器端控件,或者是在服务器端C#代码中等等。

/ 与 ~/ 区别:
/是根路径是不错,不过这个跟路径是域名的跟路径,比如你的网站是在iis里面是添加网站,这样子/跟~/都是表示跟路径,但是,如果你的程序是在某一个网站下新建虚拟目录,那么就不一样了,~/路径asp.net会帮你解析成你程序的根目录,但是/就不是了,是网站的跟目录,打个比方吧:你有一个网站,你在iis里面发布为www.abc.com,这是一个网站,然后你又做了一个网站,在iis里面你是以虚拟目录放在www.abc.com下的(就是你是在www.abc.com下右键,新建虚拟目录这样形式),比如虚拟目录名称叫test,那么这时候两个路径就不一样了,比如你这个 test虚拟目录下有一个images文件夹,文件夹里面有一个bg.jpg,那么你访问的时候其实是www.abc.com/test/images/bg.jpg,这个时候,你在test程序里面的路径如果引用这个图片的时候用的是~/images/bg.jpg是没有任何问题的,但是如果你引用的是/images/bg.jpg那就表示引用的是www.abc.com/images/bg.jpg

在IIS7下发布一个网站,在该网站下再建一个子“应用程序”,添加应用程序。然后看/ 与 ~/区别。

8.3 比较虚拟目录和应用程序

虚拟目录和应用程序是两个非常容易混淆的概念。但是在IIS 7.0中,虚拟目录和应用程序是截然不同的两个概念。本章主要介绍应用程序和应用程序池,而没有介绍虚拟目录,但是在继续讨论之前,我们必须明辨虚拟目录和应用程序之间的区别。

应用程序是一个逻辑边界,这个逻辑边界可以分隔网站及其组成部分。虚拟目录则是一个真实的指针,这个指针指向了一个本地或远程物理路径。虚拟目录总是存在于应用程序之中,一个应用程序可包括多个虚拟目录。

请看applicationHost.config文件中的以下各节内容:

<site name="Default Web Site" id="1">
<application path="/">
<virtualDirectory path="/"
physicalPath="D:websiteswwwroot" />
</application>
<application path="/Section2">
<virtualDirectory path="/"
physicalPath="D:websiteswwwrootSection2" />
</application>

<bindings>
<binding protocol="http" bindingInformation="*:80:" />
</bindings>
</site>
上述各节显示了应用程序和虚拟目录。其中,一个应用程序是根应用程序,我们用"/"表示这个应用程序,而另一个应用程序是/Section2。上述两个应用程序均包括了一个名为virtualDirectory的虚拟目录:其中的一个虚拟目录指向了D:websiteswwwroot,这个位置也是网站的根;另一个虚拟目录则指向了D:websiteswwwrootSection2,这个位置是该网站的另一个组成部分。因为这些文件夹分别位于两个不同的应用程序中,因此它们无法共享应用程序文件及文件夹。

注意,DefaultAppPool分别同时列出了两个应用程序。

这些应用程序不需要保存在同一个应用程序池中,因为这两个应用程序相互之间是分离的,因此也无法共享InProc会话状态、应用程序文件、文件夹。为了能够更清楚地解释这个例子,我们将这两个应用程序保存在同一个应用程序池中。


下面给出的示例进一步解释了应用程序和虚拟目录之间的区别:
<site name="Default Web Site" id="1">
<application path="/">
<virtualDirectory path="/"
physicalPath="D:websiteswwwroot" />
<virtualDirectory path="/Section2"
physicalPath="D:elsewhereSection2" />
</application>

<bindings>
<binding protocol="http" bindingInformation="*:80:" />
</bindings>
</site>
在这个示例中,虽然只有一个程序,但是存在两个虚拟目录。这意味着网站的根和/Section2之间没有应用程序边界。如果一个页面调用了/Section2/default.aspx,那么这个页面将使用网站根的应用程序文件夹,而无须理睬/Section2文件夹下的应用程序文件夹。

现在,DefaultAppPool中只有一个应用程序。请注意,Section2文件夹的Connections窗格中的图标与图8-1的图标有所不同。原因是:这个目录是一个虚拟目录,因此这个图标表示了一个指向一个独立物理路径的虚拟目录,但是,这个虚拟目录又从父目录中继承了应用程序的设置。这两个虚拟目录可以共享InProc会话状态和缓存,因为这两个虚拟目录是同一个应用程序的组成部分。

母版页(笔记)

-》作用:当页面中有大部分内容相同时,如何重用这部分内容,以方便后期维护呢?
以前:使用iframe嵌入页面
缺点:不利于搜索引擎蜘蛛的抓取
webform框架中提供了一种新的解决方案:母版页
-》模型:在一张纸上画好通用的内容,把会填不同内容的区域预留出来
这张纸,就被称为母版页
-》使用:定义一个母版页,在页面上定义html标签内容
使用<asp:ContentPlaceHolder>预留位置
一个母版页中可以包含多个预留区,通过ID属性进行区分
在具体页面中,可以使用@Page来设置title等信息
新建“使用母版页的web窗体”,选择已经制作好的母版页
在具体页面中使用<asp:Content>来填补预留,属性ContentPlaceHolderID对应着母版页中预留的ID属性
-》示例:嵌入js、图片
-》注意:如果引入资源,路径问题是个坑
在应用程序中,提供了一个表示根目录的方式:波浪线~
网站根目录/一般同于应用程序根目录~,如果将项目发布到一个站点的子文件夹下,就会不一致
如果静态资源也想采用这种路径的方式,通过方法this.Page.ResolveUrl("~/abc/x.jpg")实现
-》具体页面与母版页,并没有继承关系,而是在具体页面中有一个属性Master指向了母版页对象
-》补充:具体页面访问母版页的控件
this.Master.FindControl("控件的名称");

Test1.Master

 1 <%@ Master Language="C#" AutoEventWireup="true" CodeBehind="Test1.master.cs" Inherits="t1_MasterTest.masters.Test1" %>
 2 
 3 <!DOCTYPE html>
 4 
 5 <html xmlns="http://www.w3.org/1999/xhtml">
 6 <head runat="server">
 7     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 8     <title></title>
 9     <asp:ContentPlaceHolder ID="head" runat="server">
10     </asp:ContentPlaceHolder>
11 </head>
12 <body>
13     <form id="form1" runat="server">
14         1<img src="<%=this.Page.ResolveUrl("~/images/sg1.jpg") %>" width="100" height="100" />
15         <img src="/images/sg1.jpg" width="100" height="100" />
16         <br />
17         <img src="../images/sg1.jpg" width="100" height="100" />
18         <br />
19         <img src="images/sg1.jpg" width="100" height="100" />
20         <br />
21         <asp:ContentPlaceHolder ID="hello1" runat="server">
22 
23         </asp:ContentPlaceHolder>
24         23<hr />
25         <asp:ContentPlaceHolder ID="hello2" runat="server">
26 
27         </asp:ContentPlaceHolder>
28         <hr />
29         456
30     </form>
31 </body>
32 </html>

Index.aspx

 1 <%@ Page Title="" Language="C#" MasterPageFile="~/masters/Test1.Master" AutoEventWireup="true" CodeBehind="Index.aspx.cs" Inherits="t1_MasterTest.Index" %>
 2 
 3 <asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
 4     <script>
 5         alert(1);
 6     </script>
 7 </asp:Content>
 8 <asp:Content ID="Content2" ContentPlaceHolderID="hello2" runat="server">
 9     <img src="images/sg1.jpg" width="100" height="100" />
10 </asp:Content>
11 <asp:Content ID="Content3" ContentPlaceHolderID="hello1" runat="server">
12     HelloWorld!
13 </asp:Content>
原文地址:https://www.cnblogs.com/ninghongkun/p/6361774.html