Understanding Razor Syntax

MVC3新视图引擎的名字叫做Razor。ASP.NET视图引擎处理web页面,寻找包含在服务器端指令的特殊元素。正如我们前面已经提到的,标准的ASPX视图引擎依靠<%和%>元素,这是所有ASP.NET开发人员都熟悉的。

利用Razor,MVC开发团队围绕@符号引入了一组新的语法元素。大体上,虽然有几个新规则,但如果你熟悉<% %>语法,运用Razor语法应该没有太多问题。本小节中,我们将给你提供一个快速的Razor语法教程,以使你看到它们时能够认识这个新元素。

1、Creating the Project

为了演示Razor的特性和语法,让我们生成一个MVC项目。

2、Defining the Model

我们打算用一个十分简单的域模型,它只有一个域类,名为Product。添加一个文件到你的Models文件夹,名为Product.cs,并确保内容与列表5-32匹配。

Listing 5-32. Creating a Simple Domain Model Class

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Web; namespace _5_32RazorSyntax.Models
{
public class Product
{
public int ProductID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public decimal Price { get; set; }
public string Category { set; get; }
}
}

3、Defining the Controller

右击项目中的Controllers文件夹,选择“添加”,然后从弹出菜单选“控制器”。设置名字为ProductController,并从Template选项中选择empty controller。点击Add按钮以生成这个控制器类,然后编辑文件内容使它如列表5-33。

Listing 5-33. A Simple Controller

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using _5_32RazorSyntax.Models; //将Product.cs的namespace包含进来 namespace _5_32RazorSyntax.Controllers
{
public class ProductController : Controller
{
public ActionResult Index()
{
Product myProduct = new Product
{
ProductID = ,
Name = "Kayak",
Description = "A boat for one person",
Category = "Watersports",
Price = 275M
}; return View(myProduct);
} }
}

我们在这里的焦点是Razor,因此我们对MVC模型中的Controller部分设置得较为松散。Index行为方法(action method)创建了Product的一个实例,并传递给View方法(未使用repository)。

4、Creating the View

为了生成视图,在ProductController类的Index方法上点击鼠标右键,选择Add View。选中“create a strongly typed view”,并在下拉列表中选中类Product。

note 如果在下拉列表中没有看到Product类,则需要先把项目编译一遍,然后再重新创建视图。编译之后Visual Studio才会识别出model classes。

选中“使用布局或母板页”复选框,但不要拾取一个文件——只让这个文本框为空。点击添加,以生成这个视图,它将以Index.cshtml出现在Views/Product文件夹中。

5、Setting the Default Route

出于方便,我们打算告诉MVC对我们应用程序的/URL(也就是根URL,首页)请求应该被引向Product控制器的Index行为方法。要完成这一步骤,打开Global.asax文件并找到RegisterRoutes方法。在这个方法中有一个对routes.MapRoute的调用。在Default中把赋给controller属性的值从默认的”Home”修改为”Product”,如列表5-34中的黑体所示。

Listing 5-34. Setting the Controller for the Default Route

 routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Product", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);

对这个路由系统先不用着急。我们将在第11章解释它如何工作。

6、Examining a Basic Razor View

Razor视图的文件扩展名为.cshtml,而以前的MVC版本和ASP.NET Web表单所使用的是.aspx。你在MVC 3项目中仍然可以用ASPX视图引擎,但我们更喜欢用Razor引擎,它对微软的MVC开发团队来说是一个强有力的重点领域。

如果你打开Index.cshtml文件进行编辑,你将看到它的内容类似于列表5-35。这是Razor视图的起点。

Listing 5-35. A Simple Razor View

 @model _5_32RazorSyntax.Models.Product

 @{
ViewBag.Title = "Index";
} <h2>Index</h2>

7、Working with the Model Object

不管它多短,列表5-35有很多事要做。让我们从视图的第一行开始:

@model _5_32RazorSyntax.Models.Product

Razor语句以@字符开头。这里,我们用@model定义了在此定义点之后本视图中可以使用的model view。正如我们在第3章中讨论的,强类型视图让我们把模型对象(model object)传递给视图。我们可以通过@model来引用方法、字段和属性(method、field、property)。如列表5-36所示。

Listing 5-36. Referring to the Model Object

 @model _5_32RazorSyntax.Models.Product

 @{
ViewBag.Title = "Index";
} <h2>Name: @Model.Name</h2>

从上面的例子你可以看到,Razor语句通常不需要结束标记(只需用@开头),除非使用代码块才需要。注意到我们在开头第一句话中指定模型的类型时,使用的是@model(m是小写)。当我们在使用中引用模型对象时,使用的是@Model(M是大写)。

8、Defining Razor Code

上面的列表5-36演示了如何调用Razor代码,如下:

<h2>Name: @Model.Name</h2>

你不仅限于只调用模型,但这是最常用的行内标签。你可以包含任何C#语句。如列表5-37所示

Listing 5-37. Calling Arbitrary Functions with Razor

 @model _5_32RazorSyntax.Models.Product

 @{
ViewBag.Title = "Index";
} <h2>Name: @Model.Name</h2>
Time view rendered: @DateTime.Now.ToShortTimeString()

这个调用以短字符串格式返回当前时间。用Razor调用一个函数或属性时会将调用后的结果插入到页面的Html中。在上面的例子中我们用@Model.<propertyname> 的形式进行了调用,将属性的值添加到页面中。

Razor可以以十分相似的方式处理复杂的代码块。我们以@字符开始,然后进行C#编码,如列表5-38所示。

Listing 5-38. A More Complex Code Block

 @model _5_32RazorSyntax.Models.Product

 @{
ViewBag.Title = "Index";
} <h2>Name: @Model.Name</h2> @if (Model.Category == "Watersports")
{
<p>@Model.Category <b>Splash!</b></p>
}
Time view rendered: @DateTime.Now.ToShortTimeString()

在这个例子中,我们包含了一个if语句,当Product条目的Category属性是Watersports时,把附加内容插入到页面。Razor能够智能化地识别if体中的HTML标签,并把它处理为嵌入标记。它也寻找更多的@标签,处理它们并把结果放入到web页面中。

如果你想把文本内容包含在代码块中而又不以HTML元素开头,那你就需要给予Razor一个辅助工具,这就是@:标签,如列表5-39所示。

Listing 5-39. Content Inside a Code Block That Doesn’t Start with an HTML Element

 @model _5_32RazorSyntax.Models.Product

 @{
ViewBag.Title = "Index";
} <h2>Name: @Model.Name</h2> @if (Model.Category == "Watersports")
{
@:Category:@Model.Category <b>Splash!</b> //前面要显示文本Category:,因为是在代码块中,直接显示不允许,所以加上@:
}
<p />
Time view rendered: @DateTime.Now.ToShortTimeString()

如果你需要包含数行文本,每一行都不用HTML元素开始,你可以用text元素,如列表5-40所示。这等同于每一行前面缀以@:元素

Listing 5-40. Using the Text Element

 @model _5_32RazorSyntax.Models.Product

 @{
ViewBag.Title = "Index";
} <h2>Name: @Model.Name</h2> @if (Model.Category == "Watersports")
{
<text>
Category: @Model.Category <b>Splash!</b>
<pre>
Row, row, row your boat,
Gently down the stream...
</pre>
</text>
}
<p />
Time view rendered: @DateTime.Now.ToShortTimeString()

在text块中你仍然可以包含Razor标记和HTML元素。这只是当有多行要处理时,比用@:更方便些。

9、Including Multiple Functions in a Code Block

你可以使用@{开头,再用大括号}结尾来将更大范围的代码和内容组合在一起,列表5-41提供了一个演示。

Listing 5-41. Creating a Larger Code Block

 @model _5_32RazorSyntax.Models.Product

 @{
ViewBag.Title = "Index";
} <h2>Name: @Model.Name</h2> @{
if (Model.Category == "Watersports")
{
@:Category: @Model.Category <b>Splash!</b>
}
if (Model.Price > )
{
<h5>Pricey!</h5>
}
}

这里有两个if块,相互进行独立的操作。

通过@{...}来构成代码块的方法更多的用在给变量赋值。就像上面这个例子中的ViewBag.Title = "Index";一样,我们可以很容易地添加更多的赋值语句。

10、Passing Data Using the View Bag Feature

上一章我们看到了如何使用View Data特性把数据从控制器传到视图。用View Bag特性我们可以完成同样的功能。列表5-42演示了如何在Product控制器中做这件事。

Listing 5-42. Using the View Bag in the Controller

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using _5_32RazorSyntax.Models; //将Product.cs的namespace包含进来 namespace _5_32RazorSyntax.Controllers
{
public class ProductController : Controller
{
public ActionResult Index()
{
Product myProduct = new Product
{
ProductID = ,
Name = "Kayak",
Description = "A boat for one person",
Category = "Watersports",
Price = 275M
}; ViewBag.ProcessingTime = DateTime.Now.ToShortTimeString();
return View(myProduct);
} }
}

ViewBag是动态类型,这意味着你可以通过直接赋值来确定属性。例如上面的ProcessingTime属性在把当前时间赋值给它之前是不存在的,直到我们将当前时间赋值给它,它才建立起来。在视图中我们再用同样的格式从ViewBag中把数据读取出来。如列表5-43所示。

Listing 5-43. Using the View Bag in the View

 @model _5_32RazorSyntax.Models.Product

 @{
ViewBag.Title = "Index";
} <h2>Name: @Model.Name</h2> @{
if (Model.Category == "Watersports")
{
<text>
<p>Description: @Model.Description <b>(Splash!)</b></p>
<p>Category: @Model.Category</p>
</text>
}
else
{
@:Description: @Model.Description
}
}
View rendered at @ViewBag.ProcessingTime

使用ViewBag跟ViewData比起来没有明显的优势,也许会少敲几下键盘。我们提到它,是因为Visual Studio为我们创建试图时就自动使用了它,就是视图中的第一个代码块

@{

ViewBag.Title = "Index";

}

这个块含有一条语句,把字符串赋给一个名为Title的属性。在下一小节,我们将解释其意义。

11、Working with Layouts

当我们生成视图时,我们选定我们想使用布局,但我们并没有告诉Visual Studio用哪一个。如果你仔细考察添加视图对话框,你会看到一些有用的信息

对话框告诉我们如果布局已经在_viewstart文件中设置了,那就让布局引用为空(leave the layout reference blank if it is already set in a _viewstart file)如果你查看你MVC项目中的Views文件夹,你将看到一个名为_ViewStart.cshtml的文件,其内容如列表5-46所示。

Listing 5-46. The _ViewStart.cshtml File

@{

Layout = "~/Views/Shared/_Layout.cshtml";

}

MVC在生成视图时会查找_ViewStart.cshtml文件,读取这个文件中的任何指令并运用它们,就好象它是包含在视图文件中一样。这里,只有一条指令,它为这个视图设置的布局是Views/Shared文件夹中的_Layout.cshtml文件。

note 名字以下划线开头的视图文件不会返回给用户,即使直接在访问它们也不会。

当我们选中了选项表示我们要使用“Use layout or master page”,却又没告诉Visual Studio我们要使用哪一个,这个时候就是让MVC自动选择_ViewStart.cshtml。当然,我们可以在视图中明确地定义一个布局,但这种方法意味着我们项目中的每个视图不能复制同样的设置。下面我们打开这个布局文件,我们可最终理解在Index视图中调用ViewBag的意义。_Layout.cshtml的内容如列表5-44所示。

Listing 5-44. The _Layout.cshtml File

 <!DOCTYPE html>
<html>
<head>
<title>@ViewBag.Title</title>
<link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
<script src="@Url.Content("~/Scripts/jquery-1.5..min.js")" type="text/javascript"></script>
</head> <body>
@RenderBody()
</body>
</html>

布局(layout)相当于ASPX的母板页(master page)。我们在Index视图设置的ViewBag.Title属性被读取,并用作为HTML的title元素的内容。相对于ASPX样式的content placeholder部分,Razor通过调用@RenderBody()来包含进视图的身体部分。与母板页十分相似,Razor布局含有HTML、脚本、以及其它你希望在视图中避免复制的元素。这里,它包括了HTML文档的基本结构,以及Index视图将被生成的内容和插入到HTML的body元素中的内容。

12、Working Without Layouts

Razor布局是可选的。如果你在生成一个视图时未选布局选项,你将获得一个类似于列表5-45所示的模板。

Listing 5-45. A View That Doesn’t Use a Layout

 @{
Layout = null;
} <!DOCTYPE html> <html>
<head>
<title>Index</title>
</head>
<body>
<div> </div>
</body>
</html>

由于没有布局,视图必须含有生成一个HTML页面所需的全部内容,包括html、head、以及body元素。注意,这种情况下你必须明确地把Layout设置为null。如果你不这么做,视图将用_ViewStart.cshtml文件中指定的布局 — 有时经常会让你感到莫明其妙。

.net mvc笔记3_Understanding Razor Syntax的更多相关文章

  1. ASP.NET MVC 学习笔记-2.Razor语法 ASP.NET MVC 学习笔记-1.ASP.NET MVC 基础 反射的具体应用 策略模式的具体应用 责任链模式的具体应用 ServiceStack.Redis订阅发布服务的调用 C#读取XML文件的基类实现

    ASP.NET MVC 学习笔记-2.Razor语法   1.         表达式 表达式必须跟在“@”符号之后, 2.         代码块 代码块必须位于“@{}”中,并且每行代码必须以“: ...

  2. Introduction to ASP.NET Web Programming Using the Razor Syntax (C#)

    1, http://www.asp.net/web-pages/overview/getting-started/introducing-razor-syntax-c 2, Introduction ...

  3. 转发-基于ASP.NET MVC 4/5 Razor的模块化/插件式架构实现

    基于ASP.NET MVC 4/5 Razor的模块化/插件式架构实现   概述 在日常开发中, 我们经常谈起模块化/插件化架构,这样可既可以提高开效率,又可以实现良好的扩展性,尤其对于产品化的系统有 ...

  4. (转)Asp.Net Mvc视图引擎Razor介绍

    Asp.Net Mvc视图引擎Razor介绍 1.Razor介绍 程序园原创,转载请注明:http://www.kwstu.com/ArticleView/dabaomvc_2014082408205 ...

  5. Razor syntax reference for ASP.NET Core

    Razor syntax reference for ASP.NET Core Razor is a markup syntax for embedding server-based code int ...

  6. Terminologies in MVC: Part 2 (Razor Engine Syntax vs Web Form)

    By Abhishek Jaiswal :) on Mar 21, 2015 In this article we learn about Razor Engine Syntax vs Web For ...

  7. ASP.NET MVC 学习笔记-2.Razor语法

    1.         表达式 表达式必须跟在“@”符号之后, 2.         代码块 代码块必须位于“@{}”中,并且每行代码必须以“:”结尾.代码块中定义的变量可能会被同一个域中的其他块使用. ...

  8. MVC学习笔记2 - Razor语法

    Razor 同时支持 C# (C sharp) 和 VB (Visual Basic). C# 的主要 Razor 语法规则 Razor 代码封装于 @{ ... } 中 行内表达式(变量和函数)以 ...

  9. MVC中在RAZOR 模板里突然了现了 CANNOT RESOLVE SYMBOL ‘VIEWBAG’ 的错误提示

    然后在Razor中出现了@ViewBag的不可用,@Url不可用,@Html 这些变量都不能用了. 异常提示: 编译器错误消息: CS0426: 类型“XX.Model.System”中不存在类型名称 ...

随机推荐

  1. 《转载》详解 CSS 属性 - 伪类和伪元素的区别

    首先,阅读 w3c 对两者的定义: CSS 伪类用于向某些选择器添加特殊的效果. CSS 伪元素用于将特殊的效果添加到某些选择器. 可以明确两点,第一两者都与选择器相关,第二就是添加一些“特殊”的效果 ...

  2. BOOST_PP_INC_I(x)实现

    这个比较有意思,# define BOOST_PP_INC_I(x) BOOST_PP_INC_ ## x 连接在一起以后,然后定义为x+1 实现了inc功能,不过最多也就到255 # /* Copy ...

  3. 基于nginx+lua简单的灰度发布系统

    upstream.conf upstream grey_1 { keepalive 1000; server localhost:8020; } upstream grey_2 { keepalive ...

  4. caffe 配置 札记

    cudnn的配置 1. 安装前请去先官网下载cuDNN (cudnn-7.0-linux-x64-v3),建议安装v3,v4有些问题. 将cudnn-7.0-linux-x64-v3解压后会有两个文件 ...

  5. Oracle EBS-SQL (SYS-4):sys_职责查询.sql

    select t.RESPONSIBILITY_NAME from apps.FND_RESPONSIBILITY_VL t where t.RESPONSIBILITY_NAME like '%MR ...

  6. android中onStartActivityForResult无返回值问题

    在activity间跳转传递参数,常见方法是通过onStartActivityForResult来做.不过今天使用 onStartActivityForResult的时候已经在上一个activity调 ...

  7. Oracle当前用户SQL

    select sesion.sid,sesion.serial#,sesion.username,sesion.sql_id,sesion.sql_child_number,optimizer_mod ...

  8. Linux LVM硬盘管理及LVM分区扩容

    LVM磁盘管理 一.LVM简介... 1 二. LVM基本术语... 2 三. 安装LVM... 3 四. 创建和管理LVM... 4 2. 创建PV.. 6 3. 创建VG.. 7 4. 创建LV. ...

  9. [虚拟化/云][全栈demo] 为qemu增加一个PCI的watchdog外设(六)

    目的: 1. 为我们自己的watchdog写一个驱动 步骤: 通过之前的介绍,我们很容易猜想到写我们基于PCI的watchdog驱动,可以分2个步骤. 1. 探测加载PCI设备 这部分代码跟我们的设备 ...

  10. 使用MD5完成自定义Person对象的加密过程

    ---恢复内容开始--- 首先:我们对自定义Person对象的加密过程所用的方法是归档写入文件的方法. 第一步:创建Person,继承于NSObject,然后在Person.h文件遵守NSCoding ...