1.IView接口
2.IViewEngine接口
ViewEngineResult
3.注册视图引擎
//清除视图引擎 ViewEngines.Engines.Clear(); //添加视图引擎 ViewEngines.Engines.Add(new DebugDataViewEngine()); //或 添加视图引擎(顺序) ViewEngines.Engines.Insert(0,new DebugDataViewEngine());
MVC框架对视图引擎的支持是由ControllerActionInvoker类实现的,是IActionInvoker接口的内建实现。当
当直接通过IActionInvoker或IControllerFactory接口实现自己的动作调用器或控制器工厂,将无法自动地访问视图引擎特性。
一、使用Razor视图引擎
Razor视图引擎会编译应用程序的视图,以改善性能。视图会被转换成C#类,然后被编译,这是在视图中能方便包含C#代码片段的原因。
1.配置视图搜索位置
Razor视图引擎搜索属性
属性 | 描述 | 默认值 |
ViewLocationFormats MasterLocationFormats PartialViewLocationFormats |
查找视图、分部视图,以及布局的位置 |
"~/Views/{1}/{0}.cshtml", "~/Views/{1}/{0}.vbhtml", "~/Views/Shared/{0}.cshtml", |
AreaViewLocationFormats AreaMasterLocationFormats AreaPartialViewLocationFormats |
为一个区域查找视图、分部视图,以及布局的位置 |
"~/Areas/{2}/Views/{1}/{0}.cshtml", "~/Areas/{2}/Views/{1}/{0}.vbhtml", "~/Areas/{2}/Views/Shared/{0}.cshtml", "~/Areas/{2}/Views/Shared/{0}.vbhtml" |
点位符对应的参数值:
{0} 表示视图名
{1} 表示控制器名
{2} 表示区域名
创建RazorViewEngine类的派生类,修改属性值,来改变搜索位置。(要重新注册视图引擎)
public class CustomLocationViewEngine : RazorViewEngine { public CustomLocationViewEngine() { ViewLocationFormats = new string[] { "~/Views/{1}/{0}.cshtml", "~/Views/Common/{0}.cshtml" }; } }
protected void Application_Start() { AreaRegistration.RegisterAllAreas(); ViewEngines.Engines.Clear(); ViewEngines.Engines.Add(new CustomLocationViewEngine()); WebApiConfig.Register(GlobalConfiguration.Configuration); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); }
2.添加动态内容
视图的全部目的,是让开发人员将域模型的内容渲染成用户界面。通过添加动态内容的方式在运行时生成,随着不同的请求而生成不同的内容。
添加动态内容的方式
技术 | 何时使用 |
内联代码 | 用于小型的、自包含视图逻辑的片段,如if或foreach语句。这是创建动态内容的基本身段,也是一些其他方法的基础。 |
HTML辅助器方法 | 用于生成一个独立的HTML元素或小片段集合,典型地是基于视图模型或视图数据的值。MVC包含了许多有用的HTML辅助器方法,而且创建自己的辅助器方法方法也很容易。 |
分段 | 用于创建内容分段,这种分段用于插入到布局的特定位置 |
分部视图 | 用于在视图之间共享的子片段标记。分部视图也可以含有内联代码、HTML辅助器方法,以及引用其他分部视图。分部视图不调用动作方法,因此它们不能用来执行事务逻辑 |
子动作 | 用于创建可重用的UI控件,或需要含有事务逻辑的小部件。当使用子动作时,它调用一个动作方法,返回 一个视图,并把结果注入到响应流中 |
1.分段(Section:@Section Name 标签):提供一个布局的内容区域。将视图的某一部分插入到布局中哪个位置去。
在Razor对布局进行解析时,RenderSection辅助器方法会显示视图中指定名称的分段内容。视图中未包含的分段内容,会插入到布局中使用RenderBody辅助器的地方。
注:一个视图只能定义布局中被引用的分段。如果尝试在视图中定义布局中没有对应@RenderSection辅助器调用的分段,会抛出异常。
2.好的方法:
@section Header{ ......}
@section Body{ ......}
@section Footer{ ......}
-------------------------------------------
.............
@RenderSection("Header")
.............
@RenderSection("Body")
.............
@RenderSection("Footer")
(1)布局(_Layout.cshtml)中判断视图中是否定义了分段:
检查一个视图是否定义了布局中的特定分段,如果没有可以对一个分段提供默认的内容。
//判断视图是否定义了Header分段,如果没有就加载默认头部内容
@if (IsSectionDefined("Header")) { @RenderSection("Header") } else { <h4>默认头部内容</h4> }
(2)可选分段: @RenderSection("script",false)
如果视图定义了script分段,就插入到结果中,如果没有也不抛出异常。
2.分部视图(Section):应用程序中多个不同的地方使用同样的Razor标签和HTML标记片段,使用分部视图。
是含有标签和标记片段的独立的视图文件,可以被包含在其他视图中。
分部视图在布局中渲染内容。
第一步: 创建分部视图StrongPartial.cshtml(强类型)
@model IEnumerable<string> <div> 这里的信息来自于分部视图 <ul> @foreach (string str in Model) { <li> @str</li> } </ul>
@Html.ActionLink("这里是Index","Index") //根据所处理的请求,采用其控制器的信息。(调用不同控制器的index) </div>
第二步,使用@Html.Partial("分部视图名称",模型对象)使用分部视图:在List.html
@{ ViewBag.Title = "List"; Layout = null; } <h2>这是在/View/Common/下的list</h2> @*@Html.Partial("MyPartial")*@ @Html.Partial("StrongPartial",new[] { "Apple","orange","pear" })
分部视图最经常的用途之一:在布局中渲染内容。
3.子动作(Child Action):通过视图调用的动作方法。某个控制器逻辑用于应用程序的多个地方。(子动作与动作的关系,相当于分部视图与视图一样)
当希望显示某些数据驱动的“小部件”(出现在多个页面上),而且含有与主动作无关的数据时,使用子动作。
(1)定义子动作方法:
[ChildActionOnly] //确保此动作只能在视图中为子动作进行调用。 public ActionResult Time(DateTime time) { return PartialView(time); }
(2) 添加子动作视图:
@model DateTime <p> 现在时间:@Model.ToShortTimeString() </p>
(3)渲染子动作: 通用@Html.Action("子动作名称",["控制器名称"],[子动作参数])
@Html.Action("Time","Home",new{time=DateTime.Now)