MVC教程八:母版页(布局页)视图
一、母版页介绍和使用
母版页的扩展名为".cshtml",也叫做视图布局页,它相当于网页的模板。在其他网页中,只要引用了母版页,母版页的页面内容就可以自动显示出来,设计者可以修改引用的母版页中预留的部分,其他部分保持不变,这样就可以使多个页面的风格保持一致,给网页设计带来了很大的方便。
1、创建母版页视图的要点
(1)、在Views的子文件夹Shared文件夹里面添加。
(2)、以“_”前缀作为开头。
(3)、以"Layout.cshtml"作为结束。
2、MVC母版页里的三个功能点:
(1)、RenderBody-子页面内容占位符。
(2)、RenderPage-引用呈现一个页面。
(3)、RenderSection-内容占位符。
如果新建一个MVC程序,里面有没有使用母版页视图呢?查看Index视图:

从上面的截图中可以看出,Index里面只有两个DIV,但是一个基本的网页代码需要有HTML、head、body等元素标签组成,但是这里面并没有。同时,浏览index视图:

这时查看网页源代码:

从上面的截图中可以看到有HTML、head、body等HTML元素,到这里可以看出,MVC中已经使用了母版页。MVC中默认使用Shared文件夹里面的_ViewStart.cshtml视图。
二、RenderBody
RenderBody的作用是子页面内容占位符。即母版页中使用了RenderBody的地方会使用子页面的内容来代替。以_Layout视图为例:

在_Layout母版页中使用了RenderBody,所以运行的时候这部分内容将会被Index里面的内容代替。
下面我们自己重新定义一个母版页,同时定义一个子页面来使用这个母版页来查看RenderBody的作用。
1、添加母版页
在Shared文件夹上面右键添加,选择MVC5布局页

2、命名为_TestLayout

生成的模板页代码如下:
<!DOCTYPE html> <html>
<head>
<meta name="viewport" content="width=device-width" />
<title>@ViewBag.Title</title>
</head>
<body>
<div>
@RenderBody()
</div>
</body>
</html>
3、修改母版页,修改后的母版页代码如下:
<!DOCTYPE html> <html>
<head>
<meta name="viewport" content="width=device-width" />
<title>@ViewBag.Title</title>
</head>
<body>
<div>
我是母版页,在子页面中不允许更改
<!--内容页占位符-->
@RenderBody()
</div>
</body>
</html>
4、创建子页面使用母版页
在Home控制器里面添加一个ActionName为Test的Action方法,并添加视图:

生成的Test视图如下图所示:

注意:如果Layout=null,则表示不使用母版页视图。
修改Test视图也,修改后的代码如下:
@{
ViewBag.Title = "Test";
Layout = "~/Views/Shared/_TestLayout.cshtml";
}
<h2>Test</h2>
<div>
我是子页面-home控制器的Test方法
</div>
5、运行程序,浏览Test视图

通过运行结果和查看网页源代码,可以看出是母版页和子页面组成的页面。
三、RenderPage
RenderPage:引用呈现一个页面,即在一个页面中引用呈现另外一个页面,也就是说另外一个页面是这个页面的一部分。
以网页尾部布局为例说明RenderPage。
1、在Shared文件夹里面新添加一个分部页,并命名为FooterPartial。

2、修改分部也
修改后的代码如下:
<div>
我是页脚
</div>
3、在母版页中使用分部页
在RenderBody的下面使用RenderPage,RenderPage方法的参数如下图所示:

从上图中可以看出,使用RenderPage()方法的时候,只需知道分部页的路径即可,修改后的母版页代码如下:
<!DOCTYPE html> <html>
<head>
<meta name="viewport" content="width=device-width" />
<title>@ViewBag.Title</title>
</head>
<body>
<div>
我是母版页,在子页面中不允许更改
<!--内容页占位符-->
@RenderBody()
@RenderPage("_FooterPartial.cshtml")
</div>
</body>
</html>
4、运行结果

四、RenderSection
先来看下面一个例子:
在Test视图里面添加一段脚本,修改后的Test视图代码如下:

这是在运行程序,结果如下:

通过运行结果发现脚本在视图内容呈现之前先执行了,这显示不是我们想要的效果。我们希望是在整个页面都加载完成之后再执行脚本。修改布局页代码如下:
<!DOCTYPE html> <html>
<head>
<meta name="viewport" content="width=device-width" />
<title>@ViewBag.Title</title>
</head>
<body>
<div>
我是母版页,在子页面中不允许更改
<!--内容页占位符-->
@RenderBody()
<div style="color:blue">
<p>
<!---->
@RenderSection("SectionContent")
</p>
</div>
@RenderPage("_FooterPartial.cshtml")
</div> </body> </html>
子页面修改如下:

运行结果:

如果在母版页中定义了RenderSection,而在子页面中并没有对定义的RenderSection进行处理,那么结果是怎样的呢?

从上图中可以看出,如果在子页面中没有对定义的RenderSection进行处理,程序运行的时候直接就报错了:SectionContent节未定义。如果不想处理RenderSection该如何修改呢?
RenderSection方法截图如下:

如果不想处理RenderSection,那么required参数设置为false就可以了,修改后的布局页代码如下:
<!DOCTYPE html> <html>
<head>
<meta name="viewport" content="width=device-width" />
<title>@ViewBag.Title</title>
</head>
<body>
<div>
我是母版页,在子页面中不允许更改
<!--内容页占位符-->
@RenderBody()
<div style="color:blue">
<p>
<!---->
@RenderSection("SectionContent",false)
</p>
</div>
@RenderPage("_FooterPartial.cshtml")
</div> </body> </html>
这时在运行程序就可以正常运行了。
通过上面的例子,我们可以使用下面的方法解决开头例子中遇到的问题:在body元素的结束标签上面定义RenderSection,这时无论在子页面的任何位置定义script脚本,都会在页面全部加载完成以后才执行脚本。
布局页定义如下:

五、总结
1、RenderBody
在Razor引擎中没有“母版页”,取而代之的是叫做“布局”的页面(_Layout.cshtml)放在了共享视图文件夹中。在这个页面中,会看到标签里面有这样一条语句:
@RenderBody()
其实它的作用和母版页中的服务器控件类似,当创建基于此布局页面的视图时,视图的内容会和布局页面合并,而新创建视图的内容会通过布局页面的@RenderBody()方法呈现在标签之间。
这个方法不需要参数,而且只能出现一次。
2、RenderPage
从名称可以猜出来这个方法是要呈现一个页面。比如网页中固定的头部可以单独放在一个共享的视图文件中,然后在布局页面中通过这个方法调用,用法如下:
@RenderPage("_FooterPartial.cshtml")
可以带参数
@RenderPage("_FooterPartial.cshtml",new {parm="my",parm2="you"})
调用页面获取参数:
//获取RenderPage()传递过来的参数
@PageData["param"]
3、RenderSection
布局页面还有节(Section)的概念,也就是说:如果某个视图模板中定义了一个节,那么可以把它单独呈现出来,用法如下:
@RenderBody()
@RenderPage("_FooterPartial.cshtml")
//模板里添加了一个节
@RenderSection("head")
当然还要在视图中定义节,否则会出现异常:
@secion head{
//do
}
为了防止因缺少节而出现异常,可以给RenderSection()提供第2个参数:
@RenderSection("head",false)
或者
@if(IsSectionDefined("head"))
{
@RenderSection("head",false)
}
else
{
<p>head Section is not defined!</p>
}
4、@Html.Partial
Partial每次都会创建自己的TextWriter实例并且把内容缓存到内存中,最后把所有write输出的内容发送到一个MvcString对象中。
更多时候我们会使用@{Html.RenderPartial("Details");}而不是@Html.Partial。
Html.RenderPartial()和@Html.Partial的区别:
Html.RenderPartial()直接输出至当前HttpContext(因为是直接输出,所以性能好)。
Html.Partial 将视图内容直接生成一个字符串并返回(相当于有个转义的过程)。
RenderPage()和RenderPartial()的区别
RenderPage()调用的页面只能使用其传递过去的数据。
RenderPartial()是可以使用ViewData、model等数据的。
如:@{Html.RenderPartial("BasicChart",model);}
用这个重载可以在部分视图里使用强类型,然后在主视图中使用第二个参数传model过去。
@{Html.RenderPartial("BasicChart",ViewData["myData"]);}
MVC教程八:母版页(布局页)视图的更多相关文章
- 2017.3.31 spring mvc教程(七)多视图控制器
学习的博客:http://elf8848.iteye.com/blog/875830/ 我项目中所用的版本:4.2.0.博客的时间比较早,11年的,学习的是Spring3 MVC.不知道版本上有没有变 ...
- MVC学习系列5--Layout布局页和RenderSection的使用
我们开发网站项目的时候,都会遇到这样的问题:就是页面怎么统一风格,有一致的外观,在之前ASP.NET的时代,我们有两种选择,一个是使用MasterPage页,一个是手动,自己在每个页面写CSS样式,但 ...
- ASP.NET MVC中的嵌套布局页
在WEB窗体模式中,用惯了母版页,并且常有母版页嵌套的情况. 而在MVC模式下,对应母版页的,称作为布局页.默认的布局页为 ~/Views/Shared/_Layout.cshtml.默认每个页面都会 ...
- ASP.NET MVC教程八:_ViewStart.cshtml
一.引言 _ViewStart.cshtml是在ASP.NET MVC 3.0及更高版本以后出现的,用Razor模板引擎新建项目后,Views目录下面会出现一个这样的文件: 打开_ViewStart. ...
- MVC教程八:缓存过滤器
缓存过滤器用来输出页面缓存,其用法如下图所示: 注意: Duration:表示缓存多少秒;VaryByParam:表示缓存是否随地址参数而改变.OutputCache除了可以定义在Action方法上面 ...
- ASP.NET MVC 5 学习教程:修改视图和布局页
原文 ASP.NET MVC 5 学习教程:修改视图和布局页 起飞网 ASP.NET MVC 5 学习教程目录: 添加控制器 添加视图 修改视图和布局页 控制器传递数据给视图 添加模型 创建连接字符串 ...
- MVC视图布局页常用代码
1.在视图 Views 中新建文件夹 Shared 2.在 Shared 中新建布局页-母版页 _Layout.cshtml @{ Layout = null; } <!DOCTYPE h ...
- MVC的布局页,视图布局页和分布页的使用
一,结构如下图 二,布局页和视图布局页 1>使用方法一 _ViewStart.cshtml @{ Layout = "~/Views/Shared/_Layout.cshtml&quo ...
- ASP.Net MVC 布局页 模板页 使用方法详细说明
一.Views文件夹 -> Shared文件夹下的 _Layout.cshtml 母版页 @RenderBody 当创建基于_Layout.cshtml布局页面的视图时,视图的内容会和布局页面合 ...
随机推荐
- Hadoop创建/删除文件夹出错
log4j:WARN No appenders could be found for logger (org.apache.hadoop.metrics2.lib.MutableMetricsFact ...
- sudo: /etc/sudoers is owned by uid 755, should be 0
在ubuntu环境下, 想往/etc/sudoers中添加可以执行sudo操作的用户,使用root将/etc/sudoers的权限修改为755后,提示出现标题中的错误: 修正方法:将/etc/sudo ...
- [转]在 javascript 按键事件中,按键值的对照表
转自:http://www.phpweblog.net/kiyone/archive/2007/04/19/1138.html 话说谁知道怎么能精简下word生成的html代码....好大啊... 字 ...
- ASP.NET MVC中的cshtml页面中的下拉框的使用
ASP.NET MVC中的cshtml页面中的下拉框的使用 用上@Html.DropDownList 先记下来..以做备忘...
- Atitit 路径规划法attilax总结 扫描线路法
Atitit 路径规划法attilax总结 扫描线路法 2017/2/8 20:43:37[吐槽]深圳-小 2017/2/8 20:43:37 群主做什么的2017/2/10 10:03:15系统消 ...
- 将redis作为windows服务安装
1,下载redis并解压到一个目录下,然后切换到该目录下,也就是redis-server.exe文件所在的目录 2,在cmd下执行 redis-server --service-install red ...
- FLINK SQL Calcite原理
http://wuchong.me/blog/2017/03/30/flink-internals-table-and-sql-api/ https://cloud.tencent.com/devel ...
- 高级数据库及一步一步搭建versant数据库
总的来说,高级数据库课程分为分布式数据库和面向对象数据库两块.分布式数据库介绍了分布式数据库的方方面面,包括数据库系统的设计.查询处理优化.事务管理和恢复.并发控制.可靠性.安全性与目录管理等.面向对 ...
- angular.js测试框架protracotr安装所需的node版本
protractor内代码的语法是基于ES6的,比如:里面用到了展开运算符“...”,node.js 6.0以下是不支持该语法特性. 所以,安装protractor是不会报错,但运行webdriver ...
- Android 拍照
android调用camera时,可以自己写一个activity,赋上相关参数,打开前camera就可以了: 需要申请的permission,在AndroidManifest.xml中添加: < ...