ASP.NET 使用 Razor 語法 (C#) 的網頁程式設計導論

由 Tom FitzMacken 撰寫

本文將介紹使用 Razor 語法 ASP.NET 網頁的程式設計。 ASP.NET 是 Microsoft 用於在網頁伺服器上運行動態網頁的技術。 本文重點介紹如何使用 C# 程式語言。

您將學到的內容

  • 使用 Razor 語法開始 ASP.NET 網頁程式設計的八大建議。
  • 你需要掌握基本的程式設計概念。
  • ASP.NET 伺服器程式碼和 Razor 語法到底是關於什麼。

軟體版本

  • ASP.NET 網頁(Razor)3

此教學同時適用於 ASP.NET Web Pages 2。

八大程式設計技巧

本節列出幾個你在開始使用 Razor 語法撰寫伺服器程式碼時 ASP.NET 絕對需要知道的技巧。

備註

Razor 語法基於 C# 程式語言,而 C# 是 ASP.NET 網頁中最常用的語言。 不過 Razor 語法也支援 Visual Basic 語言,你看到的所有操作也可以在 Visual Basic 裡做。 詳情請參閱附錄 《Visual Basic 語言與語法》。

你可以在文章後面找到更多關於這些程式設計技術的細節。

1. 你用 @ 字元在頁面上加入程式碼

@字元開始於串聯表達式、單語句區塊和多語句區塊:

<!-- Single statement blocks  -->
@{ var total = 7; }
@{ var myMessage = "Hello World"; }

<!-- Inline expressions -->
<p>The value of your account is: @total </p>
<p>The value of myMessage is: @myMessage</p>

<!-- Multi-statement block -->
@{
    var greeting = "Welcome to our site!";
    var weekDay = DateTime.Now.DayOfWeek;
    var greetingMessage = greeting + " Today is: " + weekDay;
}
<p>The greeting is: @greetingMessage</p>

以下是網頁在瀏覽器執行時的樣貌:

Razor-Img1

小提示

HTML 編碼

當你在頁面中用字 @ 元顯示內容時,就像前面的例子一樣,ASP.NET HTML 編碼輸出。 這會用程式碼取代保留的 HTML 字元(如 <>& ),使字元能在網頁中顯示為字元,而非被解讀為 HTML 標籤或實體。 若沒有 HTML 編碼,伺服器程式碼的輸出可能無法正確顯示,並可能讓頁面暴露在安全風險之中。

如果你的目標是輸出能將標籤呈現為標記的 HTML 標記(例如段落或<p></p>強調文字),請參考本文後面的「<em></em>」章節。

你可以在 《Working with Forms》中閱讀更多關於 HTML 編碼的資訊。

2. 你用大括號包住代碼區塊

一個 代碼區塊 包含一個或多個代碼陳述句,並以大括號包覆。

<!-- Single statement block.  -->
@{ var theMonth = DateTime.Now.Month; }
<p>The numeric value of the current month: @theMonth</p>

<!-- Multi-statement block. -->
@{
    var outsideTemp = 79;
    var weatherMessage = "Hello, it is " + outsideTemp + " degrees.";
}
<p>Today's weather: @weatherMessage</p>

結果顯示在瀏覽器中:

Razor-Img2

3. 在區塊內,每個代碼語句結尾都加分號

在一個代碼區塊內,每個完整的代碼語句必須以分號結尾。 內嵌表達式不會以分號結尾。

<!-- Single-statement block -->
@{ var theMonth = DateTime.Now.Month; }

<!-- Multi-statement block -->
@{
    var outsideTemp = 79;
    var weatherMessage = "Hello, it is " + outsideTemp + " degrees.";
}

<!-- Inline expression, so no semicolon -->
<p>Today's weather: @weatherMessage</p>

4. 你用變數來儲存數值

你可以把數值儲存在 變數裡,包括字串、數字、日期等等。你用關鍵字建立一個新變數 var 。 你可以直接在 @頁面中插入變數值。

<!-- Storing a string -->
@{ var welcomeMessage = "Welcome, new members!"; }
<p>@welcomeMessage</p>

<!-- Storing a date -->
@{ var year = DateTime.Now.Year; }

<!-- Displaying a variable -->
<p>Welcome to our new members who joined in @year!</p>

結果顯示在瀏覽器中:

Razor-Img3

5. 你用雙引號包住字串的數值

字串是一串被當作文字處理的字元序列。 要指定字串,你用雙引號包住它:

@{ var myString = "This is a string literal"; }

如果你想顯示的字串包含反斜線字元( \ )或雙引號( " ),請使用帶有運算子前綴@ (在 C# 中,除非你使用逐字串,否則 \ 字元具有特殊意義。)

<!-- Embedding a backslash in a string -->
@{ var myFilePath = @"C:\MyFolder\"; }
<p>The path is: @myFilePath</p>

要嵌入雙引號,請使用逐字字串字面值並重複引號:

<!-- Embedding double quotation marks in a string -->
@{ var myQuote = @"The person said: ""Hello, today is Monday."""; }
<p>@myQuote</p>

以下是在頁面中使用這兩個例子的結果:

剃刀-IMG4

備註

請注意,這個 @ 字元同時用於 C# 中的逐字字串字面值標記,也用於標記 ASP.NET 頁中的程式碼。

6. 代碼以大小寫為區分

在 C# 中,關鍵字(如 vartrueif)和變數名稱是區分大小寫的。 以下程式碼行會產生兩個不同的變數, lastNameLastName.

@{
    var lastName = "Smith";
    var LastName = "Jones";
}

如果你宣告一個變數為 var lastName = "Smith"; ,並嘗試在頁面中引用該變數為 @LastName,你會得到的值 "Jones" 是 ,而不是 "Smith"

備註

在 Visual Basic 中,關鍵字和變數 區分大小寫。

7. 你的程式碼大多涉及物件

物件代表你可以用來編程的東西——頁面、文字框、檔案、圖片、網頁請求、電子郵件、客戶紀錄(資料庫列)等等。物件有描述其特性的屬性,你可以讀取或更改——文字框物件有Text屬性(還有其他屬性)、請求物件有Url屬性、電子郵件有From屬性,客戶物件也有FirstName屬性。 物件也有它們能執行的「動詞」方法。 範例包括檔案物件 Save 的方法、影像物件 Rotate 的方法,以及電子郵件物件的方法 Send

你經常會處理這個 Request 物件,它會提供像是頁面文字框(表單欄位)的值、請求的瀏覽器類型、頁面網址、使用者身份等資訊。以下範例說明如何存取物件的 Request 屬性,以及如何呼叫 MapPath 物件的方法 Request ,該方法會給你伺服器上頁面的絕對路徑:

<table border="1">
<tr>
    <td>Requested URL</td>
    <td>Relative Path</td>
    <td>Full Path</td>
    <td>HTTP Request Type</td>
</tr>
<tr>
    <td>@Request.Url</td>
    <td>@Request.FilePath</td>
    <td>@Request.MapPath(Request.FilePath)</td>
    <td>@Request.RequestType</td>
</tr>
</table>

結果顯示在瀏覽器中:

Razor-Img5

8. 你可以寫出做出決策的程式碼

動態網頁的一個關鍵特色是你可以根據條件決定該怎麼做。 最常見的方法是使用 陳述 if 句(以及可選 else 陳述句)。

@{
   var result = "";
   if(IsPost)
   {
      result = "This page was posted using the Submit button.";
   }
   else
   {
      result = "This was the first request for this page.";
   }
}

<!DOCTYPE html>
<html>
    <head>
        <title></title>
    </head>
<body>
<form method="POST" action="" >
  <input type="Submit" name="Submit" value="Submit"/>
  <p>@result</p>
</form>
</body>
</html>

if(IsPost)if(IsPost == true) 的簡寫形式。 除了 if 語句外,還有多種方法來測試條件、重複程式碼區塊等,這些將在本文後面詳細說明。

點擊 提交後,瀏覽器中顯示的結果如下:

Razor-Img6

小提示

HTTP GET 與 POST 方法,以及 IsPost 屬性

網頁(HTTP)所使用的協定支援非常有限數量的方法(動詞)用來向伺服器發出請求。 最常見的兩種是 GET,用於閱讀頁面,以及 POST,用於提交頁面。 一般來說,使用者第一次請求頁面時,會使用 GET 來請求該頁面。 如果使用者填寫表單後點擊提交按鈕,瀏覽器會向伺服器發送 POST 請求。

在網頁程式設計中,知道頁面是被請求為 GET 還是 POST 通常很有用,這樣你才能知道如何處理該頁面。 在 ASP.NET 網頁中,你可以使用該 IsPost 屬性來判斷請求是 GET 還是 POST。 如果請求是 POST,屬性 IsPost 會回傳 true,你可以做像是讀取表單文字框值這類操作。 你會看到許多範例,說明如何根據 的 IsPost值不同地處理頁面。

一個簡單的程式碼範例

這個過程會教你如何建立一個說明基本程式技術的頁面。 在這個例子中,你建立一個頁面讓使用者輸入兩個數字,然後它會將兩個數字加入並顯示結果。

  1. 在編輯器中建立一個新檔案,命名 為 AddNumbers.cshtml

  2. 將以下程式碼和標記複製到頁面中,替換頁面中已有的內容。

    @{
        var total = 0;
        var totalMessage = "";
        if(IsPost) {
    
            // Retrieve the numbers that the user entered.
            var num1 = Request["text1"];
            var num2 = Request["text2"];
    
            // Convert the entered strings into integers numbers and add.
            total = num1.AsInt() + num2.AsInt();
            totalMessage = "Total = " + total;
        }
    }
    
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <title>Add Numbers</title>
        <meta charset="utf-8" />
        <style type="text/css">
          body {background-color: beige; font-family: Verdana, Arial;
                margin: 50px; }
          form {padding: 10px; border-style: solid; width: 250px;}
        </style>
      </head>
    <body>
      <p>Enter two whole numbers and then click <strong>Add</strong>.</p>
      <form action="" method="post">
        <p><label for="text1">First Number:</label>
          <input type="text" name="text1" />
        </p>
        <p><label for="text2">Second Number:</label>
          <input type="text" name="text2" />
        </p>
        <p><input type="submit" value="Add" /></p>
      </form>
    
      <p>@totalMessage</p>
    
    </body>
    </html>
    

    以下是一些你要注意的事項:

    • @ 元會開始頁面中第一個程式碼區塊,並且它位於 totalMessage 頁面底部附近嵌入的變數之前。
    • 頁面頂端的區塊被括號包圍。
    • 在頂端的區塊中,所有行以分號結尾。
    • 變數 totalnum1num2totalMessage 儲存數值及一串字串。
    • 賦予 totalMessage 變數的字串值以雙引號標示。
    • 由於程式碼是區分大小寫的,當 totalMessage 變數出現在頁面底部時,其名稱必須與頂端的變數完全一致。
    • 這個表達式 num1.AsInt() + num2.AsInt() 展示了如何操作物件和方法。 每個變數的方法 AsInt 會將使用者輸入的字串轉換成一個數字(整數),讓你能對它進行算術運算。
    • 標籤 <form> 包含屬性 method="post" 。 此規定當使用者點擊 新增時,頁面會透過 HTTP POST 方法傳送至伺服器。 當頁面提交時, if(IsPost) 測試會被評估為 true,條件程式碼會執行,顯示加總數字的結果。
  3. 儲存頁面並在瀏覽器中執行。 (執行前請確定該頁面已在 檔案 工作區中被選取。)輸入兩個整數,然後點擊 新增 按鈕。

    Razor-Img7

基本程式設計概念

本文將為你介紹 ASP.NET 網頁程式設計。 這不是一份完整的考試,只是快速介紹你最常用的程式設計概念。 即便如此,它幾乎涵蓋了你開始使用 ASP.NET 網頁所需的一切。

但首先,先說點技術背景。

Razor 語法、伺服器程式碼與 ASP.NET

Razor 語法是一種簡單的程式設計語法,用於將伺服器端程式碼嵌入網頁中。 在使用 Razor 語法的網頁中,內容分為兩種:客戶端內容與伺服器程式碼。 客戶端內容是指你在網頁上習慣看到的東西:HTML 標記(元素)、樣式資訊(如 CSS)、可能的客戶端腳本如 JavaScript,以及純文字。

Razor 語法允許你將伺服器程式碼加入客戶端內容。 如果頁面中有伺服器程式碼,伺服器會先執行該程式碼,然後才會將頁面送回瀏覽器。 透過在伺服器端執行,程式碼能執行單靠客戶端內容較複雜的任務,例如存取伺服器端資料庫。 最重要的是,伺服器程式碼能動態產生客戶端內容——它可以即時產生 HTML 標記或其他內容,然後連同頁面中可能包含的任何靜態 HTML 一起傳送到瀏覽器。 從瀏覽器的角度來看,伺服器程式碼產生的客戶端內容和其他客戶端內容沒什麼不同。 如你所見,所需的伺服器程式碼相當簡單。

包含 Razor 語法的 ASP.NET 網頁會有特殊的副檔名(.cshtml.vbhtml)。 伺服器會辨識這些擴充功能,執行帶有 Razor 語法標記的程式碼,然後將頁面傳送到瀏覽器。

ASP.NET 在哪個部分扮演角色?

Razor 語法基於Microsoft一項名為 ASP.NET 的技術,而 又是基於 Microsoft .NET Framework 的。 The.NET Framework 是 Microsoft 提供的大型且全面的程式設計框架,幾乎適用於開發任何類型的電腦應用程式。 ASP.NET 是 .NET Framework 中專門為建立網頁應用程式設計的部分。 開發者利用 ASP.NET 打造了世界上許多最大且流量最高的網站。 (只要你在網站的網址中看到副檔名 .aspx ,就知道該網站是用 ASP.NET 來撰寫的。)

Razor 語法讓你擁有 ASP.NET 的全部功能,但用的是簡化語法,對初學者來說更容易學,對專家來說也更高效。 雖然這種語法簡單易用,但它與 ASP.NET 及 .NET Framework 的親戚關係,意味著隨著網站越來越複雜,你就能利用更大型框架的力量。

Razor-Img8

小提示

類別與實例

ASP.NET 伺服器程式碼使用物件,而物件又建立在類別的概念之上。 類別是物件的定義或範本。 例如,應用程式可能包含 Customer 一個類別,定義任何客戶物件所需的屬性與方法。

當應用程式需要處理實際的顧客資訊時,它會建立(或 實例化)一個顧客物件。 每個個別客戶都是該 Customer 類別的獨立實例。 每個實例支援相同的屬性和方法,但每個實例的屬性值通常不同,因為每個客戶物件都是獨一無二的。 在一個客戶物件中,該 LastName 物件可能是「Smith」;在另一個客戶物件中,該 LastName 物件可能是「Jones」。

同樣地,你網站上的任何一個網頁都是 Page 該類別的 Page 物件。 頁面上的按鈕是 Button 該類別的物件 Button ,依此類推。 每個實例都有其獨特的特性,但它們都是基於物件類別定義中所指定的。

基本語法

你之前看到了一個基本範例,教你如何建立 ASP.NET 網頁頁面,以及如何將伺服器程式碼加入 HTML 標記。 在這裡,你將學習使用 Razor 語法撰寫 ASP.NET 伺服器程式碼的基礎——也就是程式語言的規則。

如果你有程式設計經驗(尤其是你用過 C、C++、C#、Visual Basic 或 JavaScript),這裡讀到的內容應該會很熟悉。 你大概只需要熟悉如何將伺服器代碼加入到 .cshtml 檔案的標記中。

在程式碼區塊中結合文字、標記與程式碼

在伺服器程式碼區塊中,你通常想輸出文字或標記(或兩者皆有)到頁面。 如果伺服器程式碼區塊包含非程式碼的文字,應該直接渲染,ASP.NET 需要能區分該文字與程式碼。 有幾種方法可以做到這一點。

  • 將文字包圍在例如 <p></p><em></em> 這樣的 HTML 元素中:

    @if(IsPost) {
        // This line has all content between matched <p> tags.
        <p>Hello, the time is @DateTime.Now and this page is a postback!</p>
    } else {
        // All content between matched tags, followed by server code.
        <p>Hello <em>stranger</em>, today is: <br /> </p>  @DateTime.Now
    }
    

    HTML 元素可以包含文字、額外 HTML 元素以及伺服器程式碼表達式。 當 ASP.NET 看到開啟的 HTML 標籤(例如 <p>),它會將所有內容包括元素及其內容都照原樣呈現給瀏覽器,並邊做邊解析伺服器程式碼表達式。

  • 使用 @: 運算子或 <text> 元素。 輸出 @: 一行內容,包含純文字或未匹配的 HTML 標籤; <text> 該元素會包圍多行以輸出。 當你不想將 HTML 元素渲染成輸出時,這些選項非常有用。

    @if(IsPost) {
        // Plain text followed by an unmatched HTML tag and server code.
        @: The time is: <br /> @DateTime.Now
        <br/>
        // Server code and then plain text, matched tags, and more text.
        @DateTime.Now @:is the <em>current</em> time.
    }
    

    如果你想輸出多行文字或未匹配的 HTML 標籤,可以在每行前加上 @:,或是將該行包圍在元素 <text> 中。 與操作 @: 符類似,<text> 標籤由 ASP.NET 用來識別文字內容,且不會在頁面輸出中呈現。

    @if(IsPost) {
        // Repeat the previous example, but use <text> tags.
        <text>
        The time is: <br /> @DateTime.Now
        <br/>
        @DateTime.Now is the <em>current</em> time.
        </text>
    }
    
    @{
        var minTemp = 75;
        <text>It is the month of @DateTime.Now.ToString("MMMM"), and
        it's a <em>great</em> day! <br /><p>You can go swimming if it's at
        least @minTemp degrees. </p></text>
    }
    

    第一個範例重複前一個範例,但使用一對 <text> 標籤包圍文字以供渲染。 在第二個範例中, <text> and </text> 標籤包含三行,這些行皆包含部分未包含的文字及未匹配的 HTML 標籤(<br />),以及伺服器程式碼與匹配的 HTML 標籤。 此外,你也可以在每行前面個別加上 @: 運算子;這兩種方式都可以。

    備註

    當您按照本節所示使用 HTML 元素、@: 運算子或 <text> 元素輸出文字時,ASP.NET 不會將輸出內容進行 HTML 編碼。 (如前所述,ASP.NET 會編碼伺服器程式碼表達式與前置 @程式碼區塊的輸出,除非在本節特別說明。)

空白

陳述中多餘的空格(以及字串文字外)不會影響陳述:

@{ var lastName =    "Smith"; }

語句中的換行不會影響語句本身,而且你可以包裝語句以提升閱讀性。 以下陳述相同:

@{ var theName =
"Smith"; }

@{
    var
    personName
    =
    "Smith"
    ;
}

然而,你不能在字串中間繞行一條線。 下列範例無法運作:

@{ var test = "This is a long
    string"; }  // Does not work!

要將像上述程式碼那樣繞行成多行的長字串結合,有兩個選項。 你可以使用串接運算子(+),你稍後會在本文中看到。 你也可以用這個 @ 字元來建立逐字字串的字面值,就像你在本文前面看到的那樣。 你可以逐字斷開字串字面值:

@{ var longString = @"This is a
    long
    string";
}

程式碼(及標記)註解

留言讓你可以為自己或他人留下留言。 它們也允許你停用(註解掉)一段程式碼或標記,這段程式碼或標記你不想執行但暫時想保留在頁面上。

Razor 程式碼和 HTML 標記的註解語法是不同的。 與所有 Razor 程式碼一樣,Razor 註解會在伺服器上處理(然後移除)後,頁面才會被送入瀏覽器。 因此,Razor 註解語法允許你在程式碼(甚至標記)中放入註解,編輯檔案時能看到,但使用者甚至在頁面原始碼中都看不到。

對於 ASP.NET Razor 註解,請以 @* 開始,並以 *@ 結束。 評論可以是一行,也可以是多行:

@*  A one-line code comment. *@

@*
    This is a multiline code comment.
    It can continue for any number of lines.
*@

這是程式碼區塊中的一個註解:

@{
    @* This is a comment. *@
    var theVar = 17;
}

這是同一段程式碼,但那一行程式碼被註解掉,無法執行:

@{
    @* This is a comment. *@
    @* var theVar = 17;  *@
}

在程式碼區塊內,作為使用 Razor 註解語法的替代方案,你可以使用你所使用的程式語言的註解語法,例如 C#:

@{
    // This is a comment.
    var myVar = 17;
    /* This is a multi-line comment
    that uses C# commenting syntax. */
}

在 C# 中,單行註解前會加上字元 // ,多行註解則以 開頭 /* 並以 結尾 */。 (與 Razor 留言相同,C# 留言不會被渲染到瀏覽器。)

關於標記,你可能知道,可以建立一個 HTML 註解:

<!-- This is a comment.  -->

HTML 註解以 `<!--` 字元開頭,以 `-->` 字元結尾。 你可以用 HTML 註解包圍文字,也可以包圍任何你想保留但不想渲染的 HTML 標記。 此 HTML 註解將隱藏標籤及其文字的全部內容:

<!-- <p>This is my paragraph.</p>  -->

與 Razor 註解不同,HTML 留言 渲染到頁面,使用者可透過查看頁面原始碼來查看。

Razor 對巢狀的 C# 區塊有限制。 更多資訊請參閱「命名的 C# 變數與巢狀區塊產生壞掉的程式碼

變數

變數是一個命名的物件,用來儲存資料。 你可以為變數命名任何東西,但名稱必須以字母字元開頭,且不能包含空白或保留字元。

變數與資料型態

變數可以有特定的資料型別,該型態指示變數中儲存的資料種類。 你可以有字串變數儲存字串值(像是「Hello world」)、整數變數儲存整數值(像是 3 或 79),以及日期變數用來儲存各種格式的日期值(例如 4/12/2012 或 March 2009)。 而且還有很多其他資料型態可以使用。

不過,通常你不需要為變數指定類型。 大多數時候,ASP.NET 可以根據變數資料的使用方式來判斷類型。 (有時你必須指定一個類型,你會看到這種情況的例子。)

你可以用 var 關鍵字宣告變數(如果你不想指定型別),或者用型別名稱來宣告變數:

@{
    // Assigning a string to a variable.
    var greeting = "Welcome!";

    // Assigning a number to a variable.
    var theCount = 3;

    // Assigning an expression to a variable.
    var monthlyTotal = theCount + 5;

    // Assigning a date value to a variable.
    var today = DateTime.Today;

    // Assigning the current page's URL to a variable.
    var myPath = this.Request.Url;

    // Declaring variables using explicit data types.
    string name = "Joe";
    int count = 5;
    DateTime tomorrow = DateTime.Now.AddDays(1);
}

以下範例展示了網頁中變數的一些典型用途:

@{
    // Embedding the value of a variable into HTML markup.
    <p>@greeting, friends!</p>

    // Using variables as part of an inline expression.
    <p>The predicted annual total is: @( monthlyTotal * 12)</p>

    // Displaying the page URL with a variable.
    <p>The URL to this page is: @myPath</p>
}

如果你將前面的例子合併在頁面中,你會在瀏覽器中看到以下畫面:

Razor-Img9

資料型態轉換與測試

雖然 ASP.NET 通常能自動判斷資料型態,但有時無法。 因此,你可能需要透過進行明確的轉換來幫助 ASP.NET。 即使你不需要轉換類型,有時候測試看看你可能處理的資料類型會很有幫助。

最常見的情況是你必須將字串轉換成其他類型,例如整數或日期。 以下範例展示了一個典型情況,必須將字串轉換成數字。

@{
    var total = 0;

    if(IsPost) {
        // Retrieve the numbers that the user entered.
        var num1 = Request["text1"];
        var num2 = Request["text2"];
        // Convert the entered strings into integers numbers and add.
        total = num1.AsInt() + num2.AsInt();
    }
}

一般來說,使用者輸入會以串聯的形式呈現給你。 即使你已要求使用者輸入數字,即使他們輸入了一個數字,當使用者送出輸入並且您在程式碼中讀取時,資料仍然是字串格式。 因此,你必須將字串轉換成一個數字。 在範例中,如果你嘗試對這些值進行算術而不轉換,會導致以下錯誤,因為 ASP.NET 無法加兩串字串:

無法隱式地將型別 'string' 轉換成 'int'。

要將數值轉換成整數,你就呼叫這個 AsInt 方法。 如果轉換成功,你就可以將數字相加。

下表列出了一些常見的變數轉換與測試方法。

方法

說明

範例


AsInt(), IsInt()

將代表整數(例如「593」)的字串轉換為整數。

var myIntNumber = 0;
var myStringNum = "539";
if(myStringNum.IsInt()==true){
    myIntNumber = myStringNum.AsInt();
}

AsBool(), IsBool()

將像「true」或「false」這樣的字串轉換成布林型態。

var myStringBool = "True";
var myVar = myStringBool.AsBool();

AsFloat(), IsFloat()

將像「1.3」或「7.439」這類小數值的字串轉換成浮點數。

var myStringFloat = "41.432895";
var myFloatNum = myStringFloat.AsFloat();

AsDecimal(), IsDecimal()

將像「1.3」或「7.439」這類小數值的字串轉換成十進位數。 (在 ASP.NET 中,十進位數比浮點數更精確。)

var myStringDec = "10317.425";
var myDecNum = myStringDec.AsDecimal();

AsDateTime(), IsDateTime()

將代表日期與時間值的字串轉換為 ASP.NET DateTime 型別。

var myDateString = "12/27/2012";
var newDate = myDateString.AsDateTime();

ToString()

將任何其他資料型態轉換成字串。

int num1 = 17;
int num2 = 76;
// myString is set to 1776
string myString = num1.ToString() +
  num2.ToString();

操作員

運算子是一個關鍵字或字元,用來告訴 ASP.NET 在表達式中要執行哪種指令。 C# 語言(以及基於它的 Razor 語法)支援許多運算子,但你只需要辨識幾個就能開始。 下表總結了最常見的運算子。

運算子

說明

Examples


+ - * /

數值表達式中使用的數學運算子。

@(5 + 13)
@{ var netWorth = 150000; }
@{ var newTotal = netWorth * 2; }
@(newTotal / 2)

=

任務。 將陳述右側的值指派給左側物件。

var age = 17;

==

平等。 若兩者值相等,則回傳 true 。 請注意=運算子與==運算子之間的區別。

var myNum = 15;
if (myNum == 15) {
    // Do something.
}

!=

不平等。 若兩者不相等,則返回 true

var theNum = 13;
if (theNum != 15) {
    // Do something.
}

< > <= >=

小於、大於、小於或等於、大於或等於。

if (2 < 3) {
    // Do something.
}
var currentCount = 12;
if(currentCount >= 12) {
    // Do something.
}

+

串接,用於連接字串。 ASP.NET 根據表達式的資料型態,知道此運算子與加法運算子的差異。

// The displayed result is "abcdef".
@("abc" + "def")

+= -=

增量運算子與減量運算子,分別對變數加1和減1。

int theCount = 0;
theCount += 1; // Adds 1 to count

.

點。 用來區分物件及其屬性和方法。

var myUrl = Request.Url;
var count = Request["Count"].AsInt();

()

括號。 用於分組表達式及傳遞參數給方法。

@(3 + 7)
@Request.MapPath(Request.FilePath);

[]

括號。 用於存取陣列或集合中的值。

var income = Request["AnnualIncome"];

!

不。 將 true 值轉換為 false,反之亦然。 通常用作簡寫方式來測試false(即不是true)。

bool taskCompleted = false;
// Processing.
if(!taskCompleted) {
    // Continue processing
}

&& ||

邏輯 AND 與 OR 用於連結條件。

bool myTaskCompleted = false;
int totalCount = 0;
// Processing.
if(!myTaskCompleted && totalCount < 12) {
    // Continue processing.
}

程式碼中處理檔案與資料夾路徑

你經常會在程式碼中處理檔案和資料夾路徑。 以下是網站實體資料夾結構的範例,可能出現在您的開發電腦上:

C:\WebSites\MyWebSite default.cshtml datafile.txt \images Logo.jpg \styles Styles.css

以下是關於網址與路徑的一些重要細節:

  • URL 以網域名稱()http://www.example.com或伺服器名稱(http://localhosthttp://mycomputer)開頭。
  • URL 對應主機電腦上的實體路徑。 例如, http://myserver 可能對應伺服器上的資料夾 C:\websites\mywebsite
  • 虛擬路徑是程式碼中用來表示路徑的簡寫,無需指定完整路徑。 它包含網址中緊接網域或伺服器名稱的部分。 使用虛擬路徑時,你可以將程式碼移到不同的網域或伺服器,而不必更新路徑。

這裡有一個例子,幫助你理解兩者的差異:

完整網址 http://mycompanyserver/humanresources/CompanyPolicy.htm
伺服器名稱 mycompanyserver
虛擬路徑 /人力資源/CompanyPolicy.htm
物理路徑 C:\mywebsites\humanresources\CompanyPolicy.htm

虛擬根節點是 /,就像你的 C 磁碟機根節點是 。 (虛擬資料夾路徑總是使用斜線。)資料夾的虛擬路徑不必與實體資料夾名稱相同;也可以是別名。 (在生產伺服器上,虛擬路徑很少與實體路徑完全匹配。)

當你在程式碼中處理檔案和資料夾時,有時需要參考實體路徑,有時則需要參考虛擬路徑,視你處理的物件而定。 ASP.NET 提供了這些工具來在程式碼中處理檔案和資料夾路徑:Server.MapPath 方法、~ 運算子及 Href 方法。

虛擬路徑轉換為實體路徑:Server.MapPath 方法

這個 Server.MapPath 方法會將虛擬路徑(例如 /default.cshtml)轉換成絕對的實體路徑(例如 C:\WebSites\MyWebSiteFolder\default.cshtml)。 當你需要完整的實體路徑時,你都會用這個方法。 一個典型的例子是在網頁伺服器上閱讀或寫入文字檔或圖片檔時。

你通常不知道你網站在主機伺服器上的絕對物理路徑,因此此方法可以將你已知的路徑——虛擬路徑——轉換成伺服器上的對應路徑。 你將虛擬路徑傳給檔案或資料夾,方法會回傳實體路徑:

@{
    var dataFilePath = "~/dataFile.txt";
}
<!-- Displays a physical path C:\Websites\MyWebSite\datafile.txt  -->
<p>@Server.MapPath(dataFilePath)</p>

引用虛擬根:~ 運算子與 Href 方法

.cshtml.vbhtml 檔案中,你可以用 ~ 運算子參考虛擬根路徑。 這非常方便,因為你可以在網站上移動頁面,且它們包含的連結不會被破壞。 如果你將網站搬到其他地點,這也非常實用。 以下是一些範例:

@{
    var myImagesFolder = "~/images";
    var myStyleSheet = "~/styles/StyleSheet.css";
}

如果網站是 http://myserver/myapp,ASP.NET 在頁面運行時會如何處理這些路徑:

  • myImagesFolderhttp://myserver/myapp/images
  • myStyleSheet : http://myserver/myapp/styles/Stylesheet.css

(你實際上不會看到這些路徑是變數的值,但 ASP.NET 會把路徑當作變數值來處理。)

你可以在伺服器程式碼(如上)和標記中使用這個 ~ 運算子,就像這樣:

<!-- Examples of using the ~ operator in markup in ASP.NET Web Pages -->

<a href="~/Default">Home</a>
<img src="~/images/MyImages.png" />

在標記中,你可以使用 ~ 操作符來建立指向資源的路徑,例如圖片檔案、其他網頁和 CSS 檔案。 當頁面執行時,ASP.NET 會瀏覽頁面(包含程式碼與標記),並解析所有 ~ 指向適當路徑的參考。

條件邏輯與迴圈

ASP.NET 伺服器程式碼允許你根據條件執行任務,並撰寫重複特定次數語句的程式碼(也就是執行迴圈的程式碼)。

測試條件

要測試一個簡單條件,你會使用 這個 if 陳述,根據你指定的測試,該陳述會回傳真或假:

@{
  var showToday = true;
  if(showToday)
  {
    @DateTime.Today;
  }
}

關鍵字 if 開始區塊。 實際測試(條件)置於括號內,會回傳真或假。 當測試為真時執行的語句會被括號包圍。 一個 if 陳述句可以包含 else 一個區塊,該區塊指定在條件為假時要執行的陳述句:

@{
  var showToday = false;
  if(showToday)
  {
    @DateTime.Today;
  }
  else
  {
    <text>Sorry!</text>
  }
}

你可以用區 else if 塊加入多個條件:

@{
    var theBalance = 4.99;
    if(theBalance == 0)
    {
        <p>You have a zero balance.</p>
    }
    else if (theBalance  > 0 && theBalance <= 5)
    {
        <p>Your balance of $@theBalance is very low.</p>
    }
    else
    {
        <p>Your balance is: $@theBalance</p>
    }
}

在此範例中,若 if 區塊的第一個條件不為真,則檢查該 else if 條件。 若符合該條件,則執行區 else if 塊中的陳述。 若未符合任何條件,則執行區塊中的 else 語句。 你可以加入任意數量的 else if 區塊,然後以 else 區塊作為「其他所有」條件的結尾。

要測試大量條件,使用一個 switch 區塊:

@{
    var weekday = "Wednesday";
    var greeting = "";

    switch(weekday)
    {
        case "Monday":
            greeting = "Ok, it's a marvelous Monday";
            break;
        case "Tuesday":
            greeting = "It's a tremendous Tuesday";
            break;
        case "Wednesday":
            greeting = "Wild Wednesday is here!";
            break;
        default:
            greeting = "It's some other day, oh well.";
            break;
    }

    <p>Since it is @weekday, the message for today is: @greeting</p>
}

要測試的值以括號內標示(範例中為變 weekday 數)。 每個測試都使用一個以冒號 (:) 結尾的case語句。 如果語 case 句的值與測試值相符,該代碼區塊就會被執行。 你用一份 break 聲明來結尾每個案件陳述。 (如果你忘記在每個 case 區塊中加入 break,下一個 case 語句的程式碼也會執行。)一個 switch 區塊通常會在最後一個情況中包含一個 default 語句作為「所有其他」的選項,當其他情況都不成立時會執行。

瀏覽器中最後兩個條件區塊的結果如下:

Razor-Img10

迴圈程式碼

你經常需要反覆執行相同的語句。 你可以透過迴圈來實現這一點。 例如,你經常對資料集合中的每個項目執行相同的語句。 如果你確切知道要迴圈幾次,就可以使用for迴圈。 這種迴圈對於遞增或遞減計數特別有用:

@for(var i = 10; i < 21; i++)
{
    <p>Line #: @i</p>
}

迴圈以 for 關鍵字開頭,接著三個括號內的陳述,每個陳述以分號結尾。

  • 括號內的第一句話var i=10;()建立一個計數器,並將其初始化為10。 你不必命名計數 i 器——你可以使用任何變數。 當迴 for 圈運行時,計數器會自動遞增。
  • 第二個陳述i < 21;設定要計算的距離條件。 在這種情況下,你希望它能達到最大 20(也就是說,在計數器低於 21 時繼續前進)。
  • 第三句(i++ )使用遞增運算子,簡單地指定每次迴圈執行時,計數器應加1。

大括號內部是每次迴圈迭代都會執行的程式碼。 標記每次會產生一個新的段落(<p> 元素),並在輸出中加入一行,顯示( i 計數器)的值。 當你執行這個頁面時,範例會產生 11 行顯示輸出,每行的文字標示項目編號。

Razor-Img11

如果你在處理一個集合或陣列時,通常會使用 foreach 迴圈。 收藏是一組相似的物件,迴 foreach 圈讓你能對收藏中的每個項目執行任務。 這種迴圈對集合很方便,因為不像迴 for 圈,你不需要增加計數器或設定限制。 相反地, foreach 循環程式碼會直接在集合中持續進行直到完成。

例如,以下程式碼回傳集合中的 Request.ServerVariables 項目,集合是一個包含你網頁伺服器資訊的物件。 它使用 foreac h 迴圈來顯示每個項目名稱,方法是在 HTML 項目符號列表中建立新 <li> 元素。

<ul>
@foreach (var myItem in Request.ServerVariables)
{
    <li>@myItem</li>
}
</ul>

關鍵字 foreach 後接著括號,其中宣告一個代表集合中單個項目的變數(例如:var item),然後是 in 關鍵字,接下來是要遍歷的集合。 在迴圈的主體 foreach 中,你可以使用你之前宣告的變數存取目前的項目。

Razor-Img12

若要建立更通用的迴圈,請使用以下 while 陳述:

@{
    var countNum = 0;
    while (countNum < 50)
    {
        countNum += 1;
        <p>Line #@countNum: </p>
    }
}

while迴圈以關鍵字while開始,後接括號,指定迴圈繼續條件是(此處為countNum小於 50),然後是要重複的區塊。 迴圈通常會增(加)或減(減)用於計數的變數或物件。 在這個例子中,每次迴圈運行時,+= 運算子都會將 countNum 加上 1。 (要在倒數迴圈中遞減變數,你會使用遞減運算子 -=)。

物品與收藏

ASP.NET 網站中的幾乎所有東西都是物件,包括網頁本身。 本節討論你在程式碼中會經常接觸到的一些重要物件。

頁面物件

ASP.NET 中最基本的物件是頁面。 你可以直接存取頁面物件的屬性,無需任何限定物件。 以下程式碼透過 Request 物件取得頁面的檔案路徑:

@{
    var path = Request.FilePath;
}

為了清楚說明你參考的是目前頁面物件的屬性和方法,你可以選擇性地用關鍵字 this 來代表程式碼中的頁面物件。 以下是先前的程式碼範例,並 this 新增以表示該頁面:

@{
    var path = this.Request.FilePath;
}

你可以利用物件的 Page 屬性來獲取大量資訊,例如:

  • Request。 如你所見,這是關於當前請求的資訊彙整,包括請求的瀏覽器類型、頁面網址、使用者身份等。

  • Response。 這是一組關於回應(頁面)的資訊,當伺服器程式碼執行完成後,將傳送給瀏覽器。 例如,你可以利用這個特性將資訊寫入回應中。

    @{
        // Access the page's Request object to retrieve the Url.
        var pageUrl = this.Request.Url;
    }
    <a href="@pageUrl">My page</a>
    

集合物件(陣列與字典)

集合是同一類型的物件集合,例如資料庫中的物件集合Customer。 ASP.NET 包含許多內建的集合,就像集合一樣 Request.Files

你經常會處理資料集合。 兩種常見的集合類型是 陣列字典。 當你想儲存一組相似的項目,但又不想建立一個獨立變數來存放每個項目時,陣列非常有用:

@* Array block 1: Declaring a new array using braces. *@
@{
    <h3>Team Members</h3>
    string[] teamMembers = {"Matt", "Joanne", "Robert", "Nancy"};
    foreach (var person in teamMembers)
    {
        <p>@person</p>
    }
}

陣列則宣告特定的資料型別,例如 stringint、 或 DateTime。 要表示變數可以包含陣列,請在宣告後加上括號(例如 string[]int[])。 你可以透過陣列中的項目位置(索引)或使用 foreach 陳述句來存取。 陣列索引是基於零的——也就是說,第一個項目位於位置 0,第二個項目位於位置 1,依此類推。

@{
    string[] teamMembers = {"Matt", "Joanne", "Robert", "Nancy"};
    <p>The number of names in the teamMembers array: @teamMembers.Length </p>
    <p>Robert is now in position: @Array.IndexOf(teamMembers, "Robert")</p>
    <p>The array item at position 2 (zero-based) is @teamMembers[2]</p>
    <h3>Current order of team members in the list</h3>
    foreach (var name in teamMembers)
    {
        <p>@name</p>
    }
    <h3>Reversed order of team members in the list</h3>
    Array.Reverse(teamMembers);
    foreach (var reversedItem in teamMembers)
    {
        <p>@reversedItem</p>
    }
}

你可以透過取得陣 Length 列的屬性來判斷一個陣列中項目的數量。 要取得特定項目在陣列中的位置(搜尋陣列),請使用該 Array.IndexOf 方法。 你也可以執行例如反轉陣列內容的Array.Reverse方法或排序內容的Array.Sort方法。

字串陣列程式碼在瀏覽器中顯示的輸出:

Razor-Img13

字典是一組鍵值對,你提供鍵(或名稱)來設定或取回對應的值:

@{
    var myScores = new Dictionary<string, int>();
    myScores.Add("test1", 71);
    myScores.Add("test2", 82);
    myScores.Add("test3", 100);
    myScores.Add("test4", 59);
}
<p>My score on test 3 is: @myScores["test3"]%</p>
@{myScores["test4"] = 79;}
<p>My corrected score on test 4 is: @myScores["test4"]%</p>

要建立字典,你使用 new 關鍵字表示你正在建立一個新的字典物件。 你可以用 var 關鍵字將字典指派到變數上。 你用括號( ) < > 表示字典中項目的資料型態。 在聲明的結尾,你必須加上一對括號,因為這其實是一種建立新字典的方法。

要將項目加入字典,你可以呼叫 Add 字典變數的方法(myScores 此例為 ),然後指定鍵和值。 或者,你也可以用方括號標示鍵,並做簡單的指派,如下範例所示:

myScores["test4"] = 79;

要從字典取得一個數值,請在括號內指定金鑰:

var testScoreThree = myScores["test3"];

呼叫帶有參數的方法

正如你在本文前面所讀,你用來編程的物件可以有方法。 例如,一個 Database 物件可能有一種 Database.Connect 方法。 許多方法也包含一個或多個參數。 參數是你傳遞給方法的值,用以使該方法完成其任務。 例如,看看該 Request.MapPath 方法的宣告,包含三個參數:

public string MapPath(string virtualPath, string baseVirtualDir, 
    bool allowCrossAppMapping);

(這行經過折行以提高可讀性。記住,換行幾乎可以在任何地方進行,除了在用引號括起的字串內。)

此方法回傳伺服器上對應特定虛擬路徑的物理路徑。 該方法的三個參數為 virtualPathbaseVirtualDir、 和 allowCrossAppMapping。 (請注意,在宣告中,參數列出了他們會接受的資料類型。)當你呼叫這個方法時,必須提供三個參數的數值。

Razor 語法提供兩種參數傳遞方式的選項: 位置參數命名參數。 要用位置參數呼叫方法,你要依照方法宣告中指定的嚴格順序傳遞參數。 (通常你可以透過閱讀方法文件來知道這個順序。)你必須依照順序操作,且不能跳過任何參數——如有需要,會傳遞空字串()""null 是你沒有值的位置參數。

以下範例假設你網站上有一個名為 scripts 的資料夾。 程式碼會呼叫該 Request.MapPath 方法,並以正確的順序傳遞三個參數的值。 接著會顯示所產生的映射路徑。

@{
    // Pass parameters to a method using positional parameters.
    var myPathPositional = Request.MapPath("/scripts", "/", true);
}
<p>@myPathPositional</p>

當一個方法有很多參數時,你可以透過使用命名參數來讓程式碼更易讀。 要使用命名參數呼叫方法,先指定參數名稱,接著冒號(:),然後是值。 命名參數的優點是你可以以任何你想要的順序傳遞它們。 缺點是方法呼叫不夠簡潔。

以下範例使用與上述相同的方法,但使用命名參數來提供數值:

@{
    // Pass parameters to a method using named parameters.
    var myPathNamed = Request.MapPath(baseVirtualDir: "/", 
        allowCrossAppMapping: true, virtualPath: "/scripts");
}
<p>@myPathNamed</p>

如你所見,參數傳遞的順序不同。 不過,如果你執行前一個範例和這個範例,它們會回傳相同的值。

處理錯誤

Try-Catch 陳述

你的程式碼中常常會有某些陳述可能因你無法控制的原因而失敗。 例如:

  • 如果你的程式碼嘗試建立或存取檔案,可能會發生各種錯誤。 你想要的檔案可能根本不存在、可能被鎖定、程式碼可能沒有權限等等。
  • 同樣地,如果你的程式碼嘗試更新資料庫中的紀錄,可能會有權限問題,與資料庫的連線可能中斷,儲存的資料可能無效,等等。

在程式設計中,這些情況稱為 例外。 如果你的程式碼遇到例外,會產生(拋出)一個錯誤訊息,充其量只會讓使用者感到惱人:

Razor-Img14

在程式碼可能遇到例外的情況下,為了避免這類錯誤訊息,可以使用 try/catch 語句。 在陳述 try 句中,你執行你正在檢查的程式碼。 在一個或多個 catch 語句中,你可以尋找可能發生的特定錯誤(特定類型的例外)。 你可以包括任意數量的 catch 陳述,以尋找你預期的錯誤。

備註

我們建議你避免在陳述中使用此 Response.Redirect 方法 try/catch ,因為這可能導致頁面出現異常。

以下範例展示了一個頁面在第一次請求時建立文字檔,接著顯示一個按鈕讓使用者開啟該檔案。 這個範例故意使用錯誤的檔名,以引起異常。 程式碼包含 catch 兩種可能例外的語句: FileNotFoundException當檔名錯誤時會發生,以及 DirectoryNotFoundException當 ASP.NET 找不到資料夾時發生的例外。 (你可以在範例中將某個陳述取消註釋,以觀察當一切正常時其運作的狀況。)

如果你的程式碼沒處理這個例外,你會看到像前面截圖一樣的錯誤頁面。 不過,該 try/catch 區塊有助於防止使用者看到這類錯誤。

@{
    var dataFilePath = "~/dataFile.txt";
    var fileContents = "";
    var physicalPath = Server.MapPath(dataFilePath);
    var userMessage = "Hello world, the time is " + DateTime.Now;
    var userErrMsg = "";
    var errMsg = "";

    if(IsPost)
    {
        // When the user clicks the "Open File" button and posts
        // the page, try to open the created file for reading.
        try {
            // This code fails because of faulty path to the file.
            fileContents = File.ReadAllText(@"c:\batafile.txt");

            // This code works. To eliminate error on page,
            // comment the above line of code and uncomment this one.
            //fileContents = File.ReadAllText(physicalPath);
        }
        catch (FileNotFoundException ex) {
            // You can use the exception object for debugging, logging, etc.
            errMsg = ex.Message;
            // Create a friendly error message for users.
            userErrMsg = "A file could not be opened, please contact "
                + "your system administrator.";
        }
        catch (DirectoryNotFoundException ex) {
            // Similar to previous exception.
            errMsg = ex.Message;
            userErrMsg = "A directory was not found, please contact "
                + "your system administrator.";
        }
    }
    else
    {
        // The first time the page is requested, create the text file.
        File.WriteAllText(physicalPath, userMessage);
    }
}

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8" />
        <title>Try-Catch Statements</title>
    </head>
    <body>
    <form method="POST" action="" >
      <input type="Submit" name="Submit" value="Open File"/>
    </form>

    <p>@fileContents</p>
    <p>@userErrMsg</p>

    </body>
</html>

其他資源

Visual Basic 程式設計

附錄:Visual Basic 語言與語法

參考文件

ASP.NET

C# 語言