1. 程式人生 > >[ASP.NET MVC 小牛之路]03

[ASP.NET MVC 小牛之路]03

Razor是MVC3中才有的新的檢視引擎。我們知道,在ASP.NET中,ASPX的檢視引擎依靠<%和%>來呼叫C#指令。而MVC3以後有了一套新的使用@標記的Razor語法,使用起來更靈活更簡潔。下面通過一些簡單示例讓大家快速撐握Razor語法的使用。

準備工作

在演示Razor語法的使用之前,我們需要做一些準備工作。

1.開啟VS建立一個ASP.NET MVC空專案,很簡單,就不具體演示了。

2.新增一個Model。在專案的Models資料夾中新增一個名為Product的類。在這我們把前一篇C#知識點提要用到的Product類搬過來用。程式碼如下:

namespace
MvcApplication1.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.新增一個Controller。右擊專案中的Controllers資料夾,選擇新增控制器,命名如下圖所示:

點新增後,對ProdcutController中的程式碼進行如下編輯:

using System.Web.Mvc;
using MvcApplication1.Models; 

namespace MvcApplication1.Controllers
{
    public class ProductController : Controller
    {
        public ActionResult Index()
        {
            Product myProduct = new Product {
                ProductID 
= 1, Name = "蘋果", Description = "又大又紅的蘋果", Category = "水果", Price = 5.9M }; return View(myProduct); } } }

4.新增一個View。右擊Index方法,選擇新增檢視,在彈出的視窗進行如下配置:

點新增後,系統自動幫我們建立一個Product資料夾和一個Index.cshtml檔案,Index.cshtml內容如下:

@model MvcApplication1.Models.Product

@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>

5.修改預設路由。為了方便,我們應該讓應用程式啟動時直接導向我們需要的請求處理(此處是Product/Index)。開啟Global.asax檔案,找到註冊路由RegisterRoutes方法下的routes.MapRoute方法,把controller的值改為“Product”,如下所示:

routes.MapRoute(
    "Default", // 路由名稱
    "{controller}/{action}/{id}", // 帶有引數的 URL
    new { controller = "Product", action = "Index", id = UrlParameter.Optional } // 引數預設值
);

先不管這些是什麼意思,我會在後面的文章中專門介紹路由。到這,我們可以按F5,程式能正常執行,準備工作就做好了。

使用Model物件

介紹Razor語法,讓我們從Index.cshtml檔案的第一行開始:

@model MvcApplication1.Models.Product

Razor語句都是以@符號開始的。每個檢視都有自己的Model屬性(通過@Model呼叫)。上面這句程式碼的意思是將本檢視的Model屬性的型別指向MvcApplication1.Models.Product型別,這就實現了強型別。強型別的好處之一是型別安全,如果寫錯了Model物件的某個成員名,編譯器會報錯;另一個好處是在VS中可以使用VS中的程式碼智慧提示自動完成型別成員呼叫的程式碼編寫。 當然這句程式碼不要程式也可以正常執行,只是給編寫程式碼造成了一定的困難。

檢視中的Model屬性用於存放控制器(Controller)傳遞過來的model例項物件(本示例中ProductController通過“return View(myProduct)”傳遞給Index檢視),下面的程式碼演示瞭如何呼叫該model物件:

@model MvcApplication1.Models.Product

@{
    ViewBag.Title = "Index";
}
<!-- 呼叫Product例項的Name屬性 -->
<h2>名稱:@Model.Name</h2>

注意,第一行程式碼用於聲名Model屬性型別用的是@model <Model型別名>(小寫m),而呼叫控制器傳遞過來的Model物件用的是@Model.<屬性名>(大寫M)。按F5執行效果如下:

使用表示式

上面講的使用Model物件是很常用的一種Razor程式碼。其實上面示例中的@Model.Name就是一個簡單的表示式,表示向Web頁面呈現Model.Name的文字值。Razor語法中的表示式除了可以使用Model物件,也可以使用幾乎任何一個其他可訪問許可權範圍內的物件,來向Web面面輸出該物件成員的文字值。如下程式碼所示:

@model MvcApplication1.Models.Product

@{
    ViewBag.Title = "Index";
}

現在的時間是: @DateTime.Now.ToShortTimeString()

執行效果如下:

這種使用物件的簡單表示式(@DateTime.Now.ToShortTimeString()和@Model.Name),在這我們不防稱之為物件表示式。

除了物件表示式,還可以是其他任意的有返回值的表示式,如條件表示式。如下面程式碼所示:

@model MvcApplication1.Models.Product

@{
    ViewBag.Title = "Index";
}

現在的時間是: @DateTime.Now.ToShortTimeString()

<br/>@(DateTime.Now.Hour>22 ? "還早,再寫一會吧!" : "該睡覺咯!")

執行效果如下:

注意,一般使用非物件表示式時都需要用小括號括起來。

使用程式碼塊

和表示式的使用方式一樣,Razor語法中也可以使用由{}括起來的單個C#過程控制程式碼塊(如if、switch、for等)。使用方式如下:

@model MvcApplication1.Models.Product

@{
    ViewBag.Title = "Index";
}

@if (Model.Price > 5M) {
    string test = "買不起!";
    <p>@Model.Name <b>太貴了!</b> @test </p>
}

效果如下:

由{}括起來的程式碼塊內可以寫任何C#程式碼,也可以使用任何HTML標籤。但需注意的是,當控制語句內只有一句程式碼時不能像寫C#後臺程式碼一樣省略大括號。

還有一種更常用的使用程式碼塊的方式。你也可以通過以@{開始,以}閉合的方式來使用程式碼塊,它可以把多個程式碼塊放在一起,開成一個更大的程式碼塊。如下程式碼所示:

@model MvcApplication1.Models.Product

@{
    ViewBag.Title = "Index";
}
@{
    if(Model.Category=="水果"){
        string test="是一種水果。";
        @Model.Name @test
    }
    if (Model.Price > 5M) {
        string test = "買不起!";
        <p>@Model.Name <b>太貴了!</b> @test </p>
    } 
}

執行結果如下:

使用@:和text標籤

我們注意到,在程式碼塊中,要麼是C#程式碼,要麼是HTML標籤,不能直接寫純文字,純文字須包裹在HTML標籤內。但如果需要在程式碼塊中直接輸出純文字而不帶HTML標籤,則可以使用@:標籤,在程式碼塊中輸出純文字文字非常有用。如下程式碼所示:

...

@if (Model.Price > 5M) {
    @[email protected]:太貴了 。
    <br />
    @: @@:後面可以是一行除@字元以外的任意文字,包括<、>和空格,怎麼寫的就怎麼輸出。
    <br />
    @: 如果要輸出@符號,當@符號前後都有非敏感字元(如<、{、和空格等)時,可以直接使用@符號,否則需要使用兩個@符號。
}

注意@符號的使用。上面程式碼執行效果如下:

使用@:標籤在程式碼塊中輸出一行不帶html標籤的文字非常方便,但如果需要在程式碼塊中輸出續或不連續的多行純文字,則使用text標籤較為方便,如下程式碼所示:

...

@if (Model.Price > 5M) {
    <text>

    名稱:<b>@Model.Name</b><br />
    分類:<b>@Model.Description</b><br />
    價錢:<b>@Model.Price</b><br />
    
    <pre>
        測試行一: <a>aaaa</a>
        測試行二: @@ [email protected]
    </pre>

    </text>
}

執行結果:

使用ViewBag

上面講了通過Model物件來從Controller傳遞資料到View。和Model物件一樣,ViewBag物件也可以用來從Controller傳遞資料到View。下面程式碼演示瞭如何在ProductController中使用ViewBag:

public ActionResult Index()
{
    Product myProduct = new Product {
        ProductID = 1,
        Name = "蘋果",
        Description = "又大又紅的蘋果",
        Category = "水果",
        Price = 5.9M
    };
    ViewBag.TestString = "這是一行測試文字!";
    return View(myProduct); 
}

 不一樣的是,ViewBag是動態型別,其中TestString是自己定義的。ViewBag在View中的使用方式是和Model一樣,如下:

...

動態表示式解析的時間是:@ViewBag.TestString

執行結果就不貼圖了。

使用Layuot

前面我們建立一個檢視的時候,我們勾選了使用佈局和母版頁,但沒有告訴VS使用哪一個。請仔細看下圖:

這個對話方塊告訴我們“如果在Razor _viewstart中設定了此選項,則留空”。在專案的Views資料夾中,我們可以看到一個_ViewStart.cshtml檔案,裡面的內容是:

@{
    Layout = "~/Views/Shared/_Layout.cshtml";
}

MVC呈現檢視的時候,預設情況下會自動查詢_ViewStart.cshtml檔案,以它作為母版來呈現使用者請求的檢視。母版的呈現是MVC內部處理的,這種以下劃線(_)開頭的檢視檔案,一般是不能直接返回給使用者。

使用佈局或母版頁的好處是,我們不需要在每個檢視中都設定一份相同的內容。按照_ViewStart.cshtml檔案內容指示的路徑,我們找到_Layout.cshtml檔案,開啟它會發現我們在Index檢視中定義的 ViewBag.Title = "Index" 就是在這裡呼叫的:

<!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.1.min.js")" type="text/javascript"></script>
</head>

<body>
    @RenderBody()
</body>
</html>

類似於ASP.NET母版頁中的ContentPlaceHolder伺服器控制元件,在MVC中使用@RenderBody()來呈現子Web頁面的內容,它可以省去我們在每個檢視檔案中寫相同的html元素、JS和樣式等的工作。

如果建立一個檢視不想使用Layout,則可以在建立檢視的對話方塊取消“使用佈局和母版頁”選項,建立後會生成如下程式碼:

@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <title>About</title>
</head>
<body>
    <div>
        
    </div>
</body>
</html>

由於沒有使用Layout,檢視中必須包含用於呈現HTML頁面每個基本元素,而且必須指定Layout=null。

參考:
《Pro ASP.NET MVC 3 Framework》