
1 创建 MasterPage,后缀名 master, 如 xmaster
其中用 <asp:ContentPlaceHolder /> 定义空位。如:
<asp:ContentPlaceHolder ID="ContentPlaceHolder1" Runat="Server">
</asp:ContentPlaceHolder>
(1)在 NewItem 对话框里选择 "select master page", 选择上一步创建的 MasterPage产生的代码里, MasterPageFile 属性指定了 MasterPage 的位置:
<%@ Page Language="VB" MasterPageFile="~/xmaster" title="无标题页面" %>
(2)页面里用 <asp:Content /> 来添加内容到对应的空位:
<asp:Content ID="Content1" ContentPlaceHolderId="ContentPlaceHolder1" Runat="Server">
(3)内容
</asp:Content/>
(4)内容页面没有 <form id="form1" runat="server">
3 利用 MasterPage 可以使用多种语言来编写一个页面的各个部分。
4 除了在 <%@ Page %> 里面指定 MasterPage, 也可以在 webconfig 指定:
<configuration>
<systemweb>
<pages masterPageFile="~/xmaster" />
</systemweb>
</configuration>
(1)这样定义后,如果创建 Page 时选择了 master page, 则在 <%@ Page %> 里面不需要指定即可使用该 MasterPage
(2)其他页面要使用不同的 MasterPage 的话,只要用第一种方法在 Page directive 里面明确的覆盖 webconfig 里的设置即可。
(3)可以仅对一组 pages 指定 MasterPage 下例利用 webconfig 的 location 元素,设定了 Admin 目录下的页面采用的不同的 MasterPage
<configuration>
<location path="Admin">
<systemweb>
<pages masterPageFile="~/ymaster" />
</systemweb>
</location>
</configuration>
5 默认情况下,Title 在 MasterPage 中指定后,其他具体页面就都使用这个 Title
在具体页面,可以有两个办法修改 Title:
a <%@ Page title="test" %>
b 代码中:protected void Page_LoadComplete(object sender, EventArgs e) {MasterPageTitle = "Hello";}
6 访问 MasterPage 中的属性和控件。
(1)用 Master 属性来访问。
a 假设 MasterPage 中有一个 Label1, 那么在内容页面可以这样:
protected void Page_LoadComplete(object sender, EventArgs e)
{string text = (MasterFindControl("Label1") as Label)Text;}
b页面加载的次序:要获取在 MasterPage 的 Page_Load 里面设定的值,必须在内容页面的Page_LoadComplete 中来写。
(2)前面提到的 FindControl() 方法来查找 MasterPage 中的控件,是一种后期绑定的做法,一般是不安全的。因为这取决于 MasterPage 中是否存在这个 tag,如果被删除了,则会导致错误。比较好的做法是,在 MasterPage 中用属性封装对他的控件的访问;如果用 FindControl(), 则总是检查其结果是否为 null
7 指定 MasterPage 中的默认内容
(1)直接在 <asp:ControlPlaceHolder /> 标签之间指定即可。
(2)如果子页面不重新指定,则会采用该默认内容。
8 编程的方式指定 Master Page
protected void Page_PreInit(object sender, EventArgs e)
{PageMasterPageFile = "~/xmaster";}
9 嵌套的 Master Page
Master Page 可以继承自更高层次的 Master Page 但是在 VS2005 中创建这种子 Master Page 的时候,不会有默认的支持。
(1)假设有了一个 Amaster,
(2)先创建一个普通的 Bmaster,
(3)然后删除其中除了 Page directive 的其他部分。
(4)把 Page Directive 修改为如下,并加入自己要定义的 PlaceHolder:
<%@ Master MasterPageFile="~/Amaster" %>
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" Runat="server">
Hello!
<asp:ContentPlaceHolder ID="ContentPlaceHolder2" Runat="server">
</asp:ContentPlaceHolder>
</asp:Content>
(5)用嵌套的模板产生的子页面将不能采用 VS2005 的 design 模式。
10 容器特定的 Master Pages
(1)为了能兼容不同的浏览器,aspnet 20 支持多个 Master Page 在运行时将自动加载合适的 Master Page
(2)语法如下:
<%@ Page Language="VB" MasterPageFile="~/Abcmaster"
Mozilla:MasterPageFile="~/AbcMozillamaster"
Opera:MasterPageFile="~/AbcMozillamaster" %>
11 页面请求的次序
当用户请求一个用 Master Page 构建的页面时,各种事件发生的次序如下:
(1)Master Page 子控件初始化;
(2)内容页面子控件初始化;
(3)Master Page 初始化;
(4)内容页面初始化;
(5)内容页面 Page_Load;
(6)Master Page 的 Page_Load;
(7)Master Page 子控件加载;
(8)内容页面子控件加载;
注意:因为内容页面的 Page_Load 先于 Master Page 的 Page_Load,所以,如果要访问 Master Page 里的服务器控件,则必须在内容页面的 Page_LoadComplete 方法里书写代码。
12 使用缓存
(1)只有在内容页面才可以使用如下的 directive 指定缓存:
<%@ OutputCache Duration="10" Varybyparam="None" %>
(这个指令让服务器在内存里缓存该页面 10 秒钟)
(2)如果对 Master Page 指定该指令,本身并不会引发错误。但是当他的子页面下一次来获取其 Master Page 的时候,如果这时 Master Page 已经过期,则会引发一个错误。
所以实际上只能对子页面指定缓存。
HtmlRenderPartial与HtmlRenderAction这两个方法都是用来在界面上嵌入用户控件的。
HtmlRenderPartial是直接将用户控件嵌入到界面上:
<%HtmlRenderPartial("LogOnUserControl");%>
或
<%HtmlRenderPartial("~/Areas/Comm/Views/Shared/LogOnUserControlascx");%>
注意:用第一种方法时,用户控件必须放在调用者同一目录下,也可以放在View/Shared中。
HtmlRenderAction则通过Controller中的Action来调用用户控件
Controller:----用户控件所在Controller
public ActionResult UserControl() {
return PartialView(); }
View:----调用用户控件的View
<%HtmlRenderAction("UserControl","Controller");%>
RenderPartial和RenderAction都是在Aspnet
Mvc中用来显示PartialView的方法,所以在什么时候用哪个方法就是碰到的第一个问题。而要做出正确的选择就需要对这两个都有充分的了解,并且
知道其异同点。这也是本文的主题。
What
is HtmlRenderPartial
HtmlRenderPartial在Aspnet
Mvc中是用来调用PartialView的。PartialView基本上就是Aspnet
Webform中的UserControl。调用也很简单,只要在View中把PartialView的名字作为参数传递就可以。比如:
<% HtmlRenderPartial("YourPartialView", YourData);
%>
YourData是一个可选的参数。如果有,那么YourData会被赋给PartialView中的Model。如果没有,那么调用
RenderPartial的View中的Mode和ViewData会被传递给PartialView。也就是说,PartialView的数据来自于
调用的View。
What
is HtmlRenderAction
HtmlRenderAction允许你直接调用某一个Action,并把返回的结果直接显示在当前调用的View中。比如:
<% HtmlRenderAction("Show", "Tag");
%>
此时,TagController中的Show方法会被调用。由于这时调用的是一个Action方法,因此可以在此方法中完成你想要完成的各种 *** 作,比如从数据库,文件等获取数据,写数据等并返回结果。
[OutputCache(Duration=6000)]
public ActionResult
Show()
{
var tagData
= null;
//Get data
from database
//tagData =
tagServiceAllHot();
return PartialView("TagCloud",
tagData);
}
TagCloud是一个简单的PartialView文件而已。
两者的相同点
RenderPartial和RenderAction通常都被用来显示一个功能相对独立的“块”,比如说显示菜单或者导航条。
两者输出的结果都被作为调用的View的一部分显示。
两者的不同点
RenderPatial的数据来自于调用的View,而RenderAction来自自己。
RenderAction会发起一个新的Request,而RenderPatial不会。
如何选择
根据两者不同点中的第二点,由于RenderAction会调用一个新的Action方法,而Aspnet
Mvc中Action是最小的缓存单位,因此如果某一个“块”的数据比较固定,不会因为访问者的不同而发生变化,那么这时就是使用 RenderAction的时候了。
题外话,对于RenderAction会发起一个新的Request,感觉对调用页面的流程有点破坏。一个View在显示的时候,自己又发起一个
Request去获取数据来显示,显然有点破坏了作为一个View的原则:
A View
should only know how to render, but not what to render!
结束了, This is all
在 ASPNET MVC 3 中如果使用了 OutputCache,一定要在 Action 中添加下面的代码,切记!
ResponseCacheSetOmitVaryStar(true);
这是一个伴随ASPNET从10到40的OutputCache Bug,ASPNET MVC 3 是基于 ASPNET 40 的,所以也躲不过。
问题演示
下面先来体验一下不加 ResponseCacheSetOmitVaryStar(true); 的情况。
示例Action代码
[OutputCache(Duration = 120)]
public ActionResult SiteHome(int pageIndex)
{
}
注:OutputCacheLocation的默认值是OutputCacheLocationAny(服务端、客户端、代理服务器端等都进行缓存)
第一次请求:
第二次请求(F5刷新浏览器):
第三次请求(F5刷新浏览器):
接着第四次请求会返回304,第五次请求又返回200。。。
再体验一下加 ResponseCacheSetOmitVaryStar(true); 的情况。
[OutputCache(Duration = 120)]
public ActionResult SiteHome(int pageIndex)
{
ResponseCacheSetOmitVaryStar(true);
}
第一次请求:
第二次请求(F5刷新浏览器):
第三次请求(F5刷新浏览器):
注:只要在缓存有效期内,服务器一直返回304。
问题分析
1 200与304的区别
当返回状态码是200时,服务器端会将当前请求的整个页面全部发送给客户端(消耗下行带宽)。
当返回状态码是304时,由于客户端浏览器提供的 Last-Modified 时间在服务器端的缓存有效期内,服务器端只发送这个状态码,不发送页面的任何内容(几乎不消耗下行带宽),浏览器直接从本地缓存中获取内容。
所以,304的好处就是节约带宽,响应速度更快。
2 对服务端缓存的影响
加不加 ResponseCacheSetOmitVaryStar(true),服务端的缓存情况都是一样的。只是不加 SetOmitVaryStar(true) 时,对于同一个客户端浏览器,每隔一次请求,服务器端就不管客户端浏览器的缓存,重新发送页面内容,但是只要在缓存有效期内,内容还是从服务器端缓存中读取。
问题危害
ASPNET 缓存的这个诡异行为,让你在不知不觉中浪费了带宽资源。
感想
用 ASPNET 开发多年,这个伴随 ASPNET 从 10 到 40 的 OutputCache Bug 自己竟然在去年才发现。之前测试时第一次请求后按F5看返回304就以为没问题,而问题恰恰就在下一下F5,偶尔多按一下F5出现200也没特别留意。由此可见,细心对程序员来说是多么重要,很多bug、很多性能问题往往不是水平不够,而是不够细心。
优秀的程序员都是细心的人,不仅在写代码的时候细心,在生活中也同样细心。别看他木讷的样子,你对他所做的一切,他都会细心地观察到、体会到。做细心的程序员,珍惜细心的程序员!
参考微软的MSDN,
OutputCache 支持
VaryByControl="controlname"
VaryByCustom="browser | customstring"
VaryByHeader="headers"
VaryByParam="parametername"
VaryByContentEncoding="encodings"
你可以用VaryByCustom,
表示自定义输出缓存要求的任意文本。如果赋予该属性的值为 browser,缓存将随浏览器名称和主要版本信息的不同而异。 如果输入自定义字符串,则必须在应用程序的 Globalasax 文件中重写 GetVaryByCustomString 方法。
以上就是关于masterPage如何使用全部的内容,包括:masterPage如何使用、如何选择Html.RenderPartial和Html.RenderAction、mvc 中out 参数如何传值等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)