View视图的新引擎:Razor (一)
本博文不是Razor教科书,只是从为什么说Razor 视图引擎是最好的这个角度来分析,它好在哪里,为什么用它。
一直以来,ASP.NET MVC都支持 “视图引擎”的概念—采用不同语法的模板的可插拔模块。当前ASP.NET MVC “默认”的视图引擎是ASP.NET Web窗体使用的.aspx/.ascx/.master文件模板。而当今其他一些流行的ASP.NET MVC视图引擎还包括spark与NHaml。
是不是很乱,不仅乱而且复杂效率还差!而横空出世的Razor视图新引擎,给我们能优化并简化的希望!首先,Razor体现了紧凑与流畅、富有表现力。Razor尽量减少一个文件里需要敲入的字符数,给你畅快淋漓的编码体验。与大部分模板的语法不同,你不会因为需要在HTML中标注服务器端代码块而中断敲代码的快感。代码分析器足够聪明,能够从你的代码里推断出是否为服务器端代码。这使得其简洁、富有表现力的语法输入能够干净,快速,有趣。Razor非常简单,非常容易上手,你只需要了解很少的新东西就可以掌握它,使用你现有的编程语言和HTML知识就足够了。它是一个非常棒的基于模板生成HTML的标记语法的视图引擎,仅此而已无须学习更多新知识。Razor不要求什么特别的工具,使用老古董的文本编辑器也可以高效编程,比如记事本。
在添加->视图”对话框中可以选择,可能今后就没得选择了!
Razor允许你从静态的HTML页面(或者任意的文本内容)开始,添加服务器端代码使其变成动态页面。Razor的一个核心设计理念就是使编码过程更加流畅,并且只要最少的按键次数就能快速地在HTML标记中添加服务器端代码。在Razor中,你只需要用一个”@”字符就可以标识代码块的开始,与”<% %>”代码碎块不一样,Razor不需要你显式指明代码块的结束位置:
Razor分析器懂得代码块中使用的C#或VB的语法—这就是为什么上例中我们不需要显式关闭代码块的原因。Razor可以自动识别出上面的语句是独立的代码块并悄悄地为我们关闭它们。看看,即使是像“hello world”这样微不足道的例子就为我们节省了12次键盘敲击。而且在键盘上”@”字符还比”%”字符更容易按,敲起来更快也更流畅。
注:@。。。输出某个非字面值,这个就相当于ASPX<%= %>。
@(……..)形式能输出字面值,它输出的只是一个字符串。
让我们来看看另外一个简单的场景,比如说要列出一些商品(并在每样商品旁标明价格):
如果用ASP.NET现有的.ASPX标记语法,我们可能需要写类似下面的代码来动态生成一个<ul>列表,里面包含表示每个商品的<li>元素:
下面是生成同样输出的Razor版本的代码:
请注意上面”@”符号是如何开始一个“foreach”循环,并在循环内嵌入一行包含代码块的HTML语句的。因为Razor分析器知道我们在代码块里用的C#语法,它可以识别出<li>标签里的内容应该被包含在foreach代码块中,并循环处理它们。它甚至还知道末尾的“}”结束foreach循环。
Razor很聪明,还能识别出<li>标签内的@p.Name和@p.Price是服务器端代码—并且在每次循环时执行它们。另外请留心Razor在HTML和代码混合的情况下,还能推导出@p.Name和@p.Price代码块的结束位置。不需要在你的模板中添加许许多多打开/关闭标记来编写代码的感觉果然是酣畅淋漓。跟上面的foreach示例一样,你可以在if语句中直接嵌入内容(或其他C#或者VB语言元素),而不需要显式指明代码块的开始和结束位置。例如:
你可以像下面这样,使用“@{ 代码 }” 标注多行语句:
请注意上例中,变量可以被多个代码块引用—变量“message”在包含多行语句的“@{}”块中定义,但也可以被@message代码块使用。这个跟.aspx文件里的”<% %>”和”<%= %>”的语法类似。
“@()”语法允许代码块中有多个符号,例如,我们可以把上例中连接字符串和数字的代码使用”@ ()” 代码块这样重写:
当在一个if/else,foreach或者其他块语句中内嵌HTML文本时,可以考虑用一个HTML或XML标签将嵌套内容环绕起来,这样可以更清楚地标明一个文本内容块的开始。
例如,下例我使用<span>标签包围多行文本内容,而文本里还有一个代码块:
在客户端的显示结果如下—注意那个<span>标签:
如果你不想在显示文本内容时,把外面的标签也输出到客户端,那可以考虑使用<text>将嵌套内容括起来:
上面的代码在客户端的输出结果如下—请注意外面的<text>标签没有被输出:
在站点中保持一致的页面观感风格非常重要。ASP.NET 2.0引入了“母版页面(master page)”的概念,就是用来帮助在使用基于.aspx的页面或模板时实现这个功能。Razor同样也支持这个概念,它用的是“版面设计页面(layout pages)”—你可以先定义一个通用的站点模板,然后在站点其他视图或页面继承模板定义的统一观感。Razor中使用母板页,也不会有之前ASPX那样的master文件,是cshtml后缀。在使用方面,在需要放子页内容的地方调用@RenderBody()即可,这个就代替了原本在ASPX中的<asp:ContentPlaceHolder ID="MainContent" runat="server" />标签了。在子页方面,只需要放上这么一行代码就行了@{Layout = "~/Views/Shared/MyLayout.cshtml";},这就说明了当前子页要使用Mylayout这个模板页,当前的子页内容会插到母版页的@RenderBody()中去。
下面是一个简单的版面设计页面示例,文件将会被保存为“SiteLayout.cshtml”。它包含了所有要放在页面里的静态HTML文本内容和动态的服务器端代码。接着我们添加了一个名为“RenderBody()”的辅助函数,放在模板中需要根据所请求的URL而“填入”具体内容的地方:
接下来我们再创建一个名为“Home.cshtml”的视图模板子页,它只包含了必要的文本内容和代码来构成所请求页面的具体内容,外围的内容则由版面模板提供:
请留意上面在Home.cshtml文件中我们怎么来显式地设置“LayoutPage”属性。它指明了我们期望用SiteLayout.cshtml作为这个视图的版面设计模板。我们还可以在ASP.NET MVC 控制器(Controller)调用Home.cshtml这个视图模板的时候,可以指定这个版面设计文件,或者将其配置为站点默认的版面设计模板(这种情况下,我们只需要在项目中的一个文件中指定它,而所有的视图模板都会自动采用它)。当我们将Home.cshtml作为一个视图模板显示时,它会合并版面设计页和子页面的内容,然后将下面的内容发送到客户端:
更复杂的情况,如果在母板页中插入子页的内容不止一个,那就要用另一种形式了母板页@RenderSection("标识符")
子页@section 标识符{ ……内容….}
以上版面定义和在视图/页面中使用它们的语法既清晰又简练。上面列出的SiteLayout.cshtml和Home.cshtml代码没有额外的冗余的标签,没有<%@ Page %>前缀,也不需要设置其它的标签或者属性。Razor使编写出来的代码尽量简洁流畅。可以在一个文本编辑程序中打开、编辑和调整/自定义它们。在vs2010中可享受代码生成或者智能提示(Intellisense)功能。
~~~~待续~~~~