跳轉到內容

ASP.NET/頁面結構分析

來自華夏公益教科書,開放的書籍,開放的世界

基本頁面結構

[編輯 | 編輯原始碼]

除了與標準 HTML 頁面相似之外,您還會注意到 ASP.NET 頁面具有一些額外的功能。其中第一個是頁面的第一行,它包含一個帶有三個屬性的“頁面指令”。

   <%@ Page Language="VB" %>

如果頁面是用 C# 編寫的,則頁面指令將採用這種形式

   <%@ Page Language="C#" %>

頁面指令用於指定影響整個 ASP.NET 頁面的設定。ASP.NET 頁面可以用多種不同的語言編寫,因此我們必須指定此頁面使用哪種語言。debug 屬性告訴 IIS Web 伺服器(或任何其他能夠理解它的 Web 伺服器)在頁面底部列印除錯資訊。trace 屬性告訴 IIS 列印有關頁面執行的更詳細的資訊,包括跟蹤變數。頁面指令使用特殊的定界符包含

   <%@  %>

接下來你會注意到,這個頁面與普通基於 HTML 的頁面不同的是,它緊隨頁面指令之後的指令碼塊。

   <script runat="server">
     ' ASP.NET page code goes here
     Sub Page_Load()
     End Sub
   </script>

雖然指令碼塊本身在網頁中並不罕見,但這個指令碼塊很特殊,因為它包含 runat="server" 屬性。此屬性是 ASP.NET 特有的,表示此指令碼塊將包含伺服器端程式碼。在指令碼塊中,我們看到了一些 Visual Basic .NET (VB.NET) 程式碼結構的示例。第一個是註釋。Visual Basic 中的註釋以撇號開頭。撇號之後的所有內容都將被忽略。

VB.NET

   ' this is a comment in VB.NET

C#

   // this is a comment in C#

VB.NET 中沒有多行註釋定界符。每行註釋都必須以撇號開頭。

VB.NET

   ' this is a multiline comment
   ' in VB.NET

C#

   /* 
      this is a multiline comment
      in C#
   */
   

在第一個註釋下方,我們看到 Page_Load() 方法。

     Sub Page_Load()
     End Sub

方法(也稱為“子例程”、“子程式”或“函式”)是命名的程式碼塊,可以透過呼叫它們的名稱來執行。

  • 子例程 - 封裝程式碼,但不返回值給上游呼叫者。
  • 函式 - 封裝程式碼,可以返回值給上游呼叫者。

Page_Load() 方法是一個特殊的執行方法,每次頁面在瀏覽器中載入時都會執行。由於此方法在每次頁面載入時都會執行,因此它是一個定義變數和啟動許多程序的有用地方。在 Page_Load() 子例程中,我們可以看到一個 VB.NET If/Then 結構。

       If Page.IsPostBack Then
       End If

在 C# 中,它看起來像這樣

       if (Page.IsPostback) {
       }

此條件語句測試頁面是否為“回發”頁面。我們將在後面更詳細地討論回發機制。目前,請知道,此塊中的任何內容在頁面第一次載入時都不會執行。但是,如果頁面上的提交按鈕被按下,它將執行。

最後,指令碼塊結束。請注意,我們討論過的所有程式碼都在頁面的開始 HTML 標記之前發生。所有這些程式碼將在傳送任何頁面輸出到瀏覽器之前在伺服器上執行。

頁面主體中唯一不同尋常的是表單標記。表單標記在 HTML 中很常見,但這個表單標記包含我們在指令碼標記中看到的相同的 runat="server" 屬性。這應該表明您,這個標記在 ASP.NET 中也有特殊的意義。

定義和顯示變數

[編輯 | 編輯原始碼]

以下是用 VB.NET 和 C# 編寫的功能齊全的 ASP.NET 頁面。它演示了一些我們將在下面討論的概念:變數宣告、變數賦值、輸出變數以及使用 CSS 格式化輸出。以下是 VB.NET 程式碼。

<%@ Page Language="VB" trace="false" %>
<script runat="server">
  Sub Page_Load()  
      ' declare variables
      Dim strCarMake as String
      Dim strCarModel as String
      ' assign variables
      strCarMake = "Mini"
      strCarModel = "Cooper"
      ' set label text values
      lblCarMake.Text = strCarMake
      lblCarModel.Text = strCarModel
      If Page.IsPostBack
        ' postback code goes here
      End If
  End Sub
</script>
<html>
  <head>
    <title></title>
    <style type="text/css">
      .box001 {
          font-family: "trebuchet ms", verdana, sans-serif;
      }
    </style>
  </head>
  <body>
      <form runat="server">
          <asp:label id="lblCarMake" runat="server" cssclass="box001"/> 
          <asp:label id="lblCarModel" runat="server" cssclass="box001"/>
      </form>
  </body>
</html>

以及相同的 C# 頁面。

 <%@ Page Language="C#" trace="false" %>
 <script runat="server">
   void Page_Load(object sender, EventArgs e){
     // declare variables
     string strCarMake;
     string strCarModel;
     // assign variables
     strCarMake = "Mini";
     strCarModel = "Cooper";
     // set label text values
     lblCarMake.Text = strCarMake;
     lblCarModel.Text = strCarModel;
     if(Page.IsPostBack){
       // postback code goes here
     }
   }
 </script>
 <html>
    <head>
      <title></title>
      <style type="text/css">
      .box001 {
          font-family: "trebuchet ms", verdana, sans-serif;
      }
      </style>
    </head>
    <body>
      <form runat="server">
          <asp:label id="lblCarMake" runat="server" cssclass="box001"/> 
          <asp:label id="lblCarModel" runat="server" cssclass="box001"/>
      </form>
    </body>
  </html>

將此頁面儲存在伺服器上,命名為 variable_test.aspx,並在瀏覽器中載入它。您應該看到以下內容顯示

 Mini Cooper

列印兩個詞需要這麼多程式碼,但它演示了一些有用的概念。因此,讓我們透過分別檢查每個部分來仔細看看它。我們從 Page_Load() 子例程(或 C# 行話中的 void 方法)開始。該塊中發生了三件重要的事情。首先,我們聲明瞭兩個變數。在 VB.NET 中

 ' declare variables
 Dim strCarMake as String
 Dim strCarModel as String

以及在 C# 中

 // declare variables
 string strCarMake;
 string strCarModel;

在 VB.NET 中,關鍵字“Dim”是“Dimension”的縮寫。使用它表示我們想定義變數的維度,這意味著我們要為變數建立一個名稱並定義它的型別。在 C# 中,我們必須在變數名稱之前加上它的“型別”(在本例中為“string”),不需要其他內容(不要忘記在行末新增分號)。我們的第一個變數是“strCarMake”。由於我們要在此變數中儲存文字,因此我們將它定義為字串(字面意思是一串字元)。我們對 strCarModel 做同樣的事情。在這兩種情況下,我們都選擇在變數名稱前新增一個三字母字首來表示它的型別。因此,當我們在程式碼中看到 strCarMake 時,我們就知道 strCarMake 應該包含一個字串。這是一個方便的做法,但不是必需的(在 C# 中是必需的,當然)。

宣告一個變數意味著為它分配記憶體,併為它關聯一個名稱,以便我們以後可以輕鬆地引用它。但是,我們還沒有將任何內容放入我們的變數中。在接下來的幾行中,我們為它們分配值。在 VB.NET 中

 ' assign variables
 strCarMake = "Mini"
 strCarModel = "Cooper"

以及在 C# 中

 // assign variables
 strCarMake = "Mini";
 strCarModel = "Cooper";

等號在這裡(與大多數程式語言一樣)被稱為“賦值運算子”。因此,直到我們說不同,strCarMake 將包含字串“Mini”,而 strCarModel 將包含字串“Cooper”。

現在我們的變數已經宣告並賦值,但我們需要一種方法將它們顯示在我們的頁面上(這並不總是必要的,但在我們的示例中是必要的)。將變數內容回顯到螢幕上的一個簡單方法是將它們與標籤關聯。以下幾行建立了兩個標籤,並將它們的“.Text”屬性設定為等於我們的變數。字首“lbl”是“label”的縮寫,是可選的,但很有用。VB.NET

 ' set label text values
 lblCarMake.Text = strCarMake
 lblCarModel.Text = strCarModel

C#

 // set label text values
 lblCarMake.Text = strCarMake;
 lblCarModel.Text = strCarModel;

向下看頁面的主體,您會看到這些標籤放置的位置

  <asp:label id="lblCarMake" runat="server" cssclass="box001"/> 
  <asp:label id="lblCarModel" runat="server" cssclass="box001"/>

以上是稱為“ASP 控制元件”的特殊 HTML 標籤的示例。ASP 控制元件有很多型別。這種型別被稱為“標籤”。可以將標籤視為簡單的佔位符,您可以對其進行程式設計控制。這裡要特別注意的是,每個標籤的 ID 屬性都使用我們之前定義的相同名稱。當 ASP.NET 引擎看到一個標籤控制元件時,它會使用 ID 屬性來決定如何處理標籤(在本例中,應該在其中放置什麼文字)。我們已經告訴它 lblCarMake 應該包含 strCarMake 包含的任何內容。因此,第一個標籤變為“Mini”。我們還告訴它 lblCarModel 應該包含 strCarModel 包含的任何內容。因此,第二個標籤被替換為字串“Cooper”。

您會注意到,我們的<asp:label> 還有另外兩個屬性。一個是 RUNAT,它被設定為“server”。這是一個必需的屬性,讓 ASP.NET 知道要處理標籤。另一個屬性是 CSSCLASS。我們可以使用此類將 CSS 類與我們的標籤相關聯。此頁面的 CSS 定義在 HTML 標題內

    <style type="text/css">
      .box001 {
          font-family: "trebuchet ms", verdana, sans-serif;
      }
    </style>

雖然 CSS 超出了本書的範圍,但您可能很容易地看出,名為“box001”的樣式有一個名為“font-family”的屬性,它告訴任何支援 CSS 的瀏覽器以“trebuchet ms”(如果系統上可用)顯示與“box001”關聯的任何內容,或者 verdana(同上),或者任何定義為系統通用無襯線字型的字型(如果前兩個都不存在)。

關於我們的示例,還有其他幾件事需要注意。首先,看看頁面頂部,注意我們的回發塊是空的,除了一個註釋。VB.NET

      If Page.IsPostBack
        ' postback code goes here
      End If

C#

      if(Page.IsPostBack){
        // postback code goes here
      }

對於此頁面,所有操作都在頁面載入時完成(在 C# 中,良好的編碼習慣要求在括號內包含兩個引數 - “object sender, EventArgs e”)。我們甚至沒有頁面上的提交按鈕,因此無法釋出任何內容。我們包含條件語句只是為了完整性,以防我們打算以後擴充套件頁面(我們將會這樣做)。

在頁面的主體中,請注意,我們的<asp:label> 標籤巢狀在一些特殊的表單標記內,這些標記具有相同的 RUNAT 屬性

      <form runat="server">
          <asp:label id="lblCarMake" runat="server" cssclass="box001"/> 
          <asp:label id="lblCarModel" runat="server" cssclass="box001"/> 
      </form>

似乎<form> 標記和<asp:label> 標記都包含 RUNAT 屬性是多餘的。的確是多餘的。也要習慣這一點。

檢查輸出頁面

[編輯 | 編輯原始碼]

如果在瀏覽器中檢視上面的頁面,然後選擇檢視頁面的原始碼,您會注意到一些伺服器端指令碼語言的通用內容,以及一些 ASP.NET 的特定內容。為了格式化,我簡化了 INPUT 標記的 VALUE 屬性。在您看到“[...]”的地方,將是一長串難以理解的字元。

<html>
  <head>
    <title></title>
    <style type="text/css">
      .box001 {
          font-family: "trebuchet ms", verdana, sans-serif;
      }
    </style>
  </head>
  <body>
      <form name="_ctl0" method="post" action="simple_variable_test.aspx" id="_ctl0">
          <input type="hidden" name="__VIEWSTATE" value="[...]" />
          <span id="lblCarMake" class="box001">Mini</span>
          <span id="lblCarModel" class="box001">Cooper</span> 
      </form>
  </body>
</html>

伺服器端語言在安全性方面和對於專有專案的保密性方面提供了一個巨大的優勢,因為它可以隱藏大量的程式碼,使其不會被瀏覽器看到。當 Web 瀏覽器向 Web 伺服器請求頁面時,伺服器會檢查該頁面。如果伺服器識別出該頁面需要由伺服器端指令碼引擎進行處理,它會將頁面傳遞給該引擎進行處理。處理引擎(這裡指的是 ASP.NET)完成工作後,將頁面返回給 Web 伺服器,Web 伺服器再將最終產品傳遞給瀏覽器。你上面看到的程式碼是瀏覽器接收到的所有程式碼。請注意,所有 ASP.NET 特定的程式碼都消失了,儘管有一些跡象表明這是一個 ASP.NET 頁面。

Web 伺服器通常根據副檔名來確定哪些頁面需要使用哪種處理引擎。ASP.NET 頁面通常以 .aspx 結尾(儘管可以透過 Web 伺服器的自定義配置來定義其他任何副檔名)。PHP 頁面以 .php 結尾。HTML 頁面通常以 .html 或 .htm 結尾。

請注意,在頁面被處理後發生了一些變化。<asp:label> 標籤變成了普通的 <span> 標籤。它們的 CSSCLASS 屬性變成了簡單的 CLASS 屬性。它們的 ID 屬性保持不變。而神秘的 RUNAT 屬性則完全消失了。我們的 <form> 標籤還在,但它的 RUNAT 屬性不見了,其他幾個表單標籤常見的屬性也出現了。

有趣的是,除了 <span> 標籤之外,還添加了一個新的 <input> 標籤到表單中。請注意,它的屬性是“hidden”。隱藏的輸入標籤用於在 Web 程式設計中將變數的值從一個頁面傳遞到另一個頁面。如果這個表單包含一個提交按鈕,那麼我們的標籤的值將透過這個 <input> 標籤的 NAME 和 VALUE 屬性傳遞到 <form> 標籤的 ACTION 屬性中定義的頁面。在許多伺服器端程式語言中,你必須自己編寫這個功能。ASP.NET 幫你做了這個,儘管方式有點隱蔽。

華夏公益教科書