今天来简单说一下Razor视图引擎语法相关的和视图类。

添加一个MvcTest项目,继续添加一个Home控制器,完成index的视图添加。我们就在index这里分析razor视图引擎。下面是home控制器代码

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Web;
 5 using System.Web.Mvc;
 6 
 7 namespace MvcTest.Controllers
 8 {
 9     public class HomeController : Controller
10     {
11         //
12         // GET: /Home/
13 
14         public ActionResult Index()
15         {
16             return View();
17         }
18 
19     }
20 }
View Code

下面是index视图的代码,注释都在代码中,就不多说了

 1 @{
 2     Layout = null;
 3 }
 4 
 5 <!DOCTYPE html>
 6 
 7 <html>
 8 <head>
 9     <meta name="viewport" content="width=device-width" />
10     <title>Index</title>
11 </head>
12 <body>
13     <div>
14         <hr />
15         @*注意,当使用@{}时说明大括号里面都是c#代码,但razor视图同时会识别尖括号,当c#语句块中出现尖括号时,
16         razor引擎就会认为我们要输入的是html标签了,即使是不合法的html标签,例如:<sb></sb>,我们都知道这是不合法的html标签,
17         但razor视图引擎并不会判断它是否合法,他只识别尖括号。*@
18         @{  //大括号内应该是c#代码了
19             for (int i = 0; i < 10; i++)
20             {
21                 //但是这里出现了尖括号,由c#代码切换成html代码
22             <label>我是由c#代码循环出来的label标签</label>
23             <br />
24             }
25             //如果我想在html标签中输入@字符怎么办呢?
26             //<label>@</label>这样肯定是不行的,因为label中添加@,@后就应该写c#代码了,我们可以这样来完成
27             <br />
28             <label>输出特殊符号方法:@@</label>//连续两个@@,这就相当于转义
29             <hr />
30         }
31         <br />
32 
33 
34         <br />
35 
36 
37         @{
38             //这样输出的会在html最上方显示,这里涉及到了执行顺序,后面我会说到,这里面输出的html标签,在页面不会做转义,仍然以标签形式展现出来。
39             Response.Write("Response.Write方法输出的内容:<br/>输出字符串,注意我的显示位置,虽然我不是在razor视图的源代码上方,但我会在最上方显示哦 <br/> <label>我是label标签哦,而且标签没有被转义哦</label><br/><br/>");
40             <br />
41             <br />
42             
43             @Html.Raw("Html.Raw方法输出的内容:<label>我是label标签</label>,但我显示的时候可没有被转义哦,仍然以label的标签的形式显示出来了哦");
44             <br />
45             <br />
46             
47             HtmlString htmlStr = new HtmlString("<label>我是用HtmlString方式new出来的label标签,我用法很多,介于转义与不转义之间哦</label>");
48             <br />
49             @htmlStr.ToHtmlString();//转义
50             <br />
51             @htmlStr.ToString();//转义
52             <br />
53             @htmlStr//非转义
54             <br />
55             <br />
56             
57             string strHtml = "<label>我是由字符串方式显示出来的label标签,但不幸的是我没能以label标签的形式显示出来,我被转义了</label>";
58             @strHtml
59             <br />
60             <br />
61             HtmlString strHtml2 = MvcHtmlString.Create("<label>MvcHtmlString方法创建的label标签,没有被转义哦</lable>");   
62             @strHtml2 
63         }
64 
65 
66         <hr />
67 
68         <br />
69         <br />
70         这是razor视图页面类生成程序集所在位置:
71         @this.GetType().Assembly.Location
72 
73         <hr />
74         <br />
75         <br />
76         <hr />
77         **************************************************下面是加载其他页面的内容哦*******************************************************
78         <br />
79         @*在index视图中加载另一个视图的方法*@
80         @{Html.RenderPartial("sonview");}
81         *******************************************************子页页面加载完毕*************************************************************
82         <br />
83     </div>
84 </body>
85 </html>
View Code

下面是index视图中用到的一个sonview视图代码

 1 @{
 2     Layout = null;
 3 }
 4 
 5 <!DOCTYPE html>
 6 
 7 <html>
 8 <head>
 9     <meta name="viewport" content="width=device-width" />
10     <title>SonView</title>
11 </head>
12 <body>
13     <div>
14         我是由index视图加载的视图哦!!!!
15     </div>
16 </body>
17 </html>
View Code

下面是个效果图

内容似乎有些乱,忍耐一下吧。

下面我们来到电脑中看一个那个程序集路径,反编译一下,看看前台页面类

这是我反编译出来的结果,我们可以看到前台页面类呗编译成名为_Page_Views_Home_Index_cshtml(名字好长啊)类。他继承自webviewpage类,这个类还是个泛型的。

这个前台页面类好简单啊,除了Execute方法,就没什么了。我们再来看看他的父类,webviewpage类

注意看里面有个Model属性,而这个属性的类型是TModel,泛型。如果我们在前台页面类写上@model student(数据类型),这样前台页面视图就叫做强类型视图,这样Model.的时候就会有提示了。哎,这里前面似乎忘了演示了,所以可能对初学者有些难以理解。

我们在Models文件夹中新建一个Student类

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Web;
 5 
 6 namespace MvcTest.Models
 7 {
 8     public class Student
 9     {
10         public string Id{get;set;}
11         public string Name { get; set; }
12         public string Description { get; set; }
13     }
14 }
View Code

 在index视图中添加 @model MvcTest.Models.Student如图

下面我们在使用@Model.的时候,看是不是有提示会有name,Id等属性了呢,这样指定了Model类型的视图就叫做强类型视图。通过反编译我们可以看到这个model的类型也是通过泛型父类传递的。

而第二天中的控制器与视图之间传递数据的几种方法中的一种ViewData在webviewpage<TModel>中,我们可以看到她就是一个dic类型,下面我们看webviewpage类,

在这里我们又看到几个眼熟的属性不是,viewbag,viewdata,context。我们继续往下挖,看webpagebase类

但是这个类中似乎没有什么我们感兴趣的东西,那么我们就继续挖,看webpagerenderingbase类

这里面属性的东西太多了吧,cache,pagecontext,request,response,server,session。至此,我们应该明白为什么我们可以在视图里面访问那么多属性了吧。

下面我们在分析一下控制器,我们在反编译工具中查找Controller这个类,注意,这个类是mvc命名空间下的,默认的反编译工具中是没有的,我们可以在项目文件夹中找到相关的dll,项目中的路径~/packages/Microsoft.AspNet.Mvc.4.0.20710.0/lib/net40/System.Web.Mvc.dll具体因为版本,可能路径也有所不同,将这个文件放在反编译工具中,查找controller这个类。

这个类中的东西太多了,我只截了一部分图,我们常用的,也证明一下为什么我们可以在我们的控制器中可以访问到那么多的属性。

下面我们再简单阐述一下视图的加载过程。这样说,每个视图加载过程中都会先加载所经过每个文件夹中的_ViewStart.cshtml文件。可能有些人没有理解。我们看下项目中的views文件夹

如果访问index.cshtml视图,因为该视图在home文件夹中,而home文件夹又在views文件夹中,所以说要访问index.cshtml文件就要经过views文件夹,在经过home文件夹。但是在views文件夹中有_ViewStart.cshtml文件,所以就要先加载这个文件。如果在home文件夹中还有个_ViewStart.cshmtl文件,这个文件也会被加载。那我们就来看看_ViewStart.cshtml中有什么东西吧。

也没有什么内容,Layout是一个布局变量,会传递给我们将要访问的视图页面。这就是为什么我们每个视图页面中Layout=null的原因了,之前给Layout赋值,到具体视图后我们又将该值清空掉了。我们没有使用布局页,这有些类似于模板。我们知道有些网站很多内容都是一样的,这样我们就可以将内容一样的部分写到模板中,而具体视图写具体的内容,用法很简单。填充内容,大家可以自己试一下。当然也可以不用模板页。今天就说到这里喽,该去吃午饭了,哈哈