官术网_书友最值得收藏!

第2章 第一個(gè)ASP.NET應(yīng)用的單文件版本

第1章實(shí)現(xiàn)的第一個(gè)ASP.NET應(yīng)用示例,展示了集成開(kāi)發(fā)工具開(kāi)發(fā)ASP.NET應(yīng)用的全貌。讀者可能也體會(huì)到,無(wú)需對(duì)ASP.NET框架本身作深入了解,利用Visual Studio.NET就可以開(kāi)發(fā)出很好的ASP.NET應(yīng)用。雖然筆者鼓勵(lì)大家盡量用Visual Studio.NET開(kāi)發(fā)ASP.NET應(yīng)用,但在某些情況下,譬如手頭沒(méi)有集成開(kāi)發(fā)工具或希望著手更多的事情以加深對(duì)ASP.NET的理解時(shí),編寫(xiě)單文件版本的ASP.NET應(yīng)用可能是個(gè)好注意。單文件版本的ASP.NET應(yīng)用中的代碼和界面混在同一個(gè).aspx文件中,在第一次被請(qǐng)求時(shí),它被動(dòng)態(tài)編譯成程序集。這樣對(duì)于開(kāi)發(fā)人員,就不用顯式地調(diào)用相應(yīng)編程語(yǔ)言的編譯器編譯隱藏代碼文件了。

本章主要內(nèi)容如下:

● Web窗體的基本語(yǔ)法

● 客戶(hù)端引發(fā)服務(wù)器端事件的底層實(shí)現(xiàn)

● 使用跟蹤排除錯(cuò)誤

● 單文件版本的ASP.NET應(yīng)用開(kāi)發(fā)步驟

2.1 預(yù)備知識(shí)

為了順利編寫(xiě)單文件版本的ASP.NET應(yīng)用,讀者需要了解基本的窗體語(yǔ)法知識(shí)。

提示

這里僅提供有關(guān)窗體語(yǔ)法的一個(gè)基本介紹,進(jìn)一步的介紹讀者可以參考本書(shū)第3章。

先看一個(gè)非常簡(jiǎn)單的.aspx文件,該文件返回“Hello”給客戶(hù):

    [Visual Basic]
    <%@ Page language="vb" %>
    <%-- 演示基于單文件的ASP.NET頁(yè)面 --%>
    <%
      Response.Write("<p>Hello")
    %>
    [C#]
    <%@ Page language="C#" %>
    <%-- 演示基于單文件的ASP.NET頁(yè)面 --%>
    <%
      Response.Write("<p>Hello");
    %>

第一行代碼是@ Page指令。利用@ Page指令的Language屬性設(shè)置頁(yè)面的編程語(yǔ)言。因?yàn)樵撝噶钤诜?wù)器端執(zhí)行,所以被包圍在<%和%>之前。

第二行為服務(wù)器端的注釋語(yǔ)句。

第三行用<%聲明一段服務(wù)端代碼塊的開(kāi)始。

第四行利用Response.Write方法向客戶(hù)端寫(xiě)回“Hello”字符串。“<p>”表示一個(gè)段落標(biāo)志。

第五行用%>聲明一段服務(wù)端代碼塊的結(jié)束。

對(duì)于Response.Write方法,存在一種簡(jiǎn)化的方式,可以直接把其輸出放在“<%=”和“%>”直接,例如:

    [Visual Basic]
    <%@ Page language="vb" %>
    <% dim I as Integer
      For I=0 to 5
      %>
        <font size="<%=i%>"> <p>Hello World! </font>
    <% Next %>
    [C#]
    <%@ Page language="c#" %>
    <%
      for(int i=0;i<6;i++)
      {
      %>
        <font size="<%=i%>"> <p>Hello World! </font>
    <% } %>

執(zhí)行結(jié)果如圖2-1所示。

圖2-1 執(zhí)行結(jié)果

與Active Server Pages (ASP)不同,在ASP.NET的代碼塊(在<%和%>標(biāo)志之間)中不能聲明函數(shù)或子例程。函數(shù)或子例程只能在<Script>和</Script>標(biāo)志之間定義。例如下面的代碼演示了例程Hello的定義及其使用:

    [Visual Basic]
    <%@ Page language="vb" %>
    <Script runat="server">
      '定義例程
      sub sayHello()
        Response.Write("<p>Hello")
      end sub
    </Script>
    <%--
      調(diào)用例程
    --%>
    <% sayHello() %>
    [C#]
    <%@ Page language="c#" %>
    <Script runat="server">
      //定義例程
      void sayHello()
      {
        Response.Write("<p>Hello");
      }
    </Script>
    <%--
      調(diào)用例程
    --%>
    <% sayHello(); %>

上述頁(yè)面向客戶(hù)返回Hello。

上面的示例表明,在<Script></Script>代碼塊中使用注釋的方法跟在代碼隱藏文件中使用注釋的方法相同。一定要把Script的runat屬性設(shè)置為server,否則代碼將按默認(rèn)設(shè)置在客戶(hù)端運(yùn)行。

提示

請(qǐng)讀者一定要弄清楚代碼運(yùn)行的位置,客戶(hù)端代碼的編程主要跟文檔對(duì)象模型,并且其語(yǔ)言為解釋型的腳本語(yǔ)言。而服務(wù)器端的代碼可以充分利用服務(wù)器端的各種資源,編程語(yǔ)言為編譯型的語(yǔ)言,并且可以動(dòng)態(tài)發(fā)出客戶(hù)端代碼,例如:

                      [Visual Basic]
                      <%@ Page language="vb" %>
                      <Script runat="server">
                        '定義例程
                        sub sayHello()
                          Response.Write(" <Script language=JScript> ")
                          Response.Write("document.write('<p>Client Hello');")
                          Response.Write("</" & "Script>")
                          end sub
                      </Script>
                      <% sayHello() %>
                      [C#]
                      <%@ Page language="C#" %>
                      <Script runat="server">
                        //定義例程
                        void sayHello()
                        {
                          Response.Write(" <Script language=JScript> ");
                          Response.Write("document.write('<p>Client Hello');");
                          Response.Write("</" + "Script>");
                        }
                      </Script>
                      <% sayHello(); %>

在服務(wù)器端編寫(xiě)的客戶(hù)端代碼可以直接放到客戶(hù)端腳本塊中。上面的代碼可以修改為:

    [Visual Basic]
    <%@ Page language="vb" %>
    <Script language=JScript>
      document.write('<p>Client Hello');
    </Script>
    [C#]
    <%@ Page language="c#" %>
    <Script language=JScript>
      document.write('<p>Client Hello');
    </Script>

修改后的代碼顯得更好讀一些。

提示

對(duì)于.aspx文件內(nèi)的HTML標(biāo)志,ASP.NET框架不會(huì)保持不變,只對(duì)特定的ASPX標(biāo)志進(jìn)行處理。

要想順利地設(shè)計(jì)出.aspx文件,還要掌握如何往Web窗體頁(yè)中添加Web服務(wù)器控件和HTTP控件。Web服務(wù)器控件在服務(wù)器端運(yùn)行,它不直接對(duì)應(yīng)到HTML元素,而是在請(qǐng)求時(shí)被動(dòng)態(tài)呈現(xiàn)為合適的HTML元素。一個(gè)HTTM控件相當(dāng)于一個(gè)HTML標(biāo)志元素,例如HTML Button控件相當(dāng)于Type屬性為“button”的INPUT HTML元素:

<INPUT type="button" >

還可以繼續(xù)指定該INPUT元素的其他屬性,例如Value、OnClick等,而這些屬性由客戶(hù)端的瀏覽器直接解釋?zhuān)?/p>

<INPUT type="button" onclick="this.value='client clicked'" value="Button">

但是,ASP.NET框架為HTML標(biāo)志增添了runat屬性,該屬性默認(rèn)為“client”,可以通過(guò)將runat設(shè)置為server,把HTML控件轉(zhuǎn)變?yōu)榉?wù)器端的控件。這時(shí)允許在服務(wù)器端的腳本中添加跟該控件相關(guān)的代碼。例如下面的代碼在單擊HTML Button控件后,在服務(wù)器端激活OnServerClick事件:

    [Visual Basic]
    <%@ Page language="vb" %>
    <Script runat="server">
    sub Button1_ServerClick(sender as object,e as System.EventArgs)
      Button1.Value="Server Clicked"
    end sub
    </Script>
    <html>
    <title>演示HTML服務(wù)器端控件</title>
    <body>
      <form runat="server">
        <INPUT type="button"
                      OnServerClick="Button1_ServerClick"
                      value="Click Me!"
                      id="Button1"
                      runat="server">
      </form>
    </body>
    </html>
    [C#]
    <%@ Page language="cs" %>
    <Script runat="server">
    void Button1_ServerClick(object sender, System.EventArgs e)
    {
      Button1.Value="Server Clicked";
    }
    </Script>
    <html>
    <title>演示HTML服務(wù)器端控件</title>
    <body>
      <form runat="server">
        <INPUT type="button"
                      OnServerClick="Button1_ServerClick"
                      value="Click Me!"
                      id="Button1"
                      runat="server">
      </form>
    </body>
    </html>

從瀏覽器請(qǐng)求該網(wǎng)頁(yè),將顯示標(biāo)題為“Click Me!”的按鈕,單擊該按鈕后,按鈕的標(biāo)題修改為“Server Cliicked”。

讀者可能對(duì)上述執(zhí)行結(jié)果表示不解,客戶(hù)端引發(fā)的事件怎么就神不知鬼不覺(jué)地傳到了服務(wù)器端呢?服務(wù)器端又如何區(qū)分是哪個(gè)控件引發(fā)的事件呢?為了回答這個(gè)問(wèn)題,我們看看該.aspx文件產(chǎn)生的回應(yīng)HTML文件:

    <html>
    <title>演示HTML服務(wù)器端控件</title>
    <body>
      <form name="_ctl0" method="post" action="demo6.aspx" id="_ctl0">
    <input type="hidden" name="__EVENTTARGET" value="" />
    <input type="hidden" name="__EVENTARGUMENT" value="" />
    <input                   type="hidden"                   name="__VIEWSTATE"
value="dDwxOTI0MjI4NTEyO3Q8O2w8aTwxPjs+O2w8dDw7bDxpPDE+Oz47bDx0PHA8bDx2YWx1Z
Ts+O2w8U2VydmVyIENsaWNrZWQ7Pj47Oz47Pj47Pj47PlHYIMOTlQB7/IiD17MuoycLy603" />
    <Script language="javaScript">
    <!--
        function __doPostBack(eventTarget, eventArgument) {
            var theform = document._ctl0;
            theform.__EVENTTARGET.value = eventTarget;
            theform.__EVENTARGUMENT.value = eventArgument;
            theform.submit();
        }
    // -->
    </Script>
        <input   language="javaScript"   onclick="__doPostBack('Button1','')"   name="Button1"
id="Button1" type="button" value="Server Clicked" />
      </form>
    </body>
    </html>

提示

展開(kāi)瀏覽器的【查看】菜單,單擊【源文件】將打開(kāi)記事本顯示上述內(nèi)容。

下面我將對(duì)產(chǎn)生的HTML文件做仔細(xì)說(shuō)明,以幫助讀者弄明服務(wù)器如何處理客戶(hù)端引發(fā)的事件。

首先查看<form>元素,在.aspx文件中,通過(guò)下面的代碼添加了一個(gè)<form>元素(也就是一個(gè)HTML控件):

      <form runat="server">
      …
      </form>

因?yàn)橹付ㄔ赟erver端運(yùn)行,所以ASP.NET將對(duì)該標(biāo)志進(jìn)行翻譯,翻譯的結(jié)果包括:

● 設(shè)定Form元素的相關(guān)屬性,例如name、id、action等屬性。

● 添加3個(gè)隱藏域:一個(gè)隱藏域用以保存引發(fā)表單被發(fā)送的HTML控件,另一個(gè)隱藏域用以保存事件參數(shù),還有一個(gè)用以保存跟服務(wù)器端控件狀態(tài)數(shù)據(jù),這個(gè)隱藏域在服務(wù)端被稱(chēng)為狀態(tài)視圖對(duì)象。前兩個(gè)隱藏域是服務(wù)器端能夠處理客戶(hù)端事件的關(guān)鍵之一。

.aspx文件中的HTML按鈕控件也是一個(gè)服務(wù)器端控件,所以ASP.NET框架也要負(fù)責(zé)把它翻譯成合適的HTML代碼,翻譯后的結(jié)果包括:

● 設(shè)置了name屬性。

● 設(shè)置了按鈕的客戶(hù)端腳本語(yǔ)言屬性(language屬性)。

● 重寫(xiě)了OnClick屬性(該屬性是在客戶(hù)單擊按鈕后執(zhí)行的代碼)。OnClick以按鈕的name屬性值為第一個(gè)參數(shù)調(diào)用客戶(hù)端的函數(shù)__doPostBack。__doPostBack根據(jù)傳入的兩個(gè)參數(shù)設(shè)置隱藏域__EVENTTARGET和隱藏域__EVENTARGUMENT的值,然后通過(guò)表單的submit方法向服務(wù)器回發(fā)網(wǎng)頁(yè)。

提示

上面的討論進(jìn)一步說(shuō)明了服務(wù)器端的HTML控件的特點(diǎn),它們總是會(huì)在服務(wù)器端進(jìn)行適當(dāng)?shù)奶幚砗螅欧祷亟o客戶(hù),而客戶(hù)端的HTML控件僅是一個(gè)HTML標(biāo)志,ASP.NET框架不做任何處理而直接將其返回。

服務(wù)器接收到回發(fā)的請(qǐng)求后,通過(guò)檢查表單的隱藏域__EVENTTARGET獲得引發(fā)回發(fā)事件的HTML控件的name,從隱藏域__EVENTARGUMENT獲得跟事件處理相關(guān)的數(shù)據(jù),接下來(lái),ASP.NET根據(jù)name查找相應(yīng)的對(duì)象,并以事件處理參數(shù)調(diào)用該對(duì)象相應(yīng)的事件處理代碼。

從上面的討論可知,為了在服務(wù)器端處理服務(wù)器控件的事件,必須滿(mǎn)足如下要求:

● 該控件必須在服務(wù)器端運(yùn)行。

● 該控件必須包含在一個(gè)服務(wù)器端運(yùn)行的HTML Form控件內(nèi)。

● 該控件的name屬性必須惟一的設(shè)置。

提示

可以指定服務(wù)器端控件的name屬性,但在ASP.NET呈現(xiàn)該控件時(shí),總是會(huì)根據(jù)該控件的UniqueID屬性重新設(shè)置客戶(hù)端HTML元素的name屬性,以確保其惟一性。

我們將在本書(shū)的后續(xù)章節(jié)中對(duì)服務(wù)器端事件處理的深入討論。現(xiàn)在讀者只要知道可以編寫(xiě)服務(wù)端控件(包括服務(wù)端的HTML控件和Web控件)的事件處理代碼,這些事件在客戶(hù)端引發(fā),但在服務(wù)器上處理,ASP.NET框架通過(guò)兩個(gè)隱藏域傳遞跟引發(fā)事件的控件和相關(guān)事件參數(shù)。

對(duì)HTML控件,我們還想指出很重要的一點(diǎn),那就是仍然可能指定客戶(hù)端的事件響應(yīng)代碼。

    [Visual Basic]
    <%@ Page language="vb" %>
    <Script runat="server">
    sub Button1_ServerClick(sender as object,e as System.EventArgs)
      Button1.Value="Server Clicked"
    end sub
    </Script>
    <html>
    <title>演示HTML服務(wù)器端控件</title>
    <body>
      <form runat="server">
        <INPUT type="button"
              OnServerClick="Button1_ServerClick"
              onmouseover="this.style.backgroundColor='yellow'"
                  onmouseout="this.style.backgroundColor='lightgreen'"
                  style="font: 8pt verdana;
                      background-color:lightgreen;
                      border-color:black;
                      height:30;
                      width:200"
              id="Button1"
              runat="server">
      </form>
    </body>
    </html>
    [C#]
    <%@ Page language="cs" %>
    <Script runat="server">
    void Button1_ServerClick(object sender, System.EventArgs e)
    {
      Button1.Value="Server Clicked";
    }
    </Script>
    <html>
    <title>演示HTML服務(wù)器端控件</title>
    <body>
      <form runat="server">
        <INPUT type="button"
              OnServerClick="Button1_ServerClick"
              onmouseover="this.style.backgroundColor='yellow'"
                  onmouseout="this.style.backgroundColor='lightgreen'"
                  style="font: 8pt verdana;
                      background-color:lightgreen;
                      border-color:black;
                      height:30;
                      width:200"
              id="Button1"
              runat="server">
      </form>
    </body>
    </html>

提示

ASP.NET框架只支持有限個(gè)事件的服務(wù)器端的處理,例如單擊事件等。因?yàn)榉?wù)器端上的事件處理會(huì)涉及到一次客戶(hù)到服務(wù)器的一個(gè)往返行程,這樣對(duì)一些高頻的鼠標(biāo)事件,例如onmouseover,放到客戶(hù)端處理更合適。

如果該控件單擊將引發(fā)表單回發(fā),那么客戶(hù)端處理OnClick事件要小心,因?yàn)锳SP.NET會(huì)自動(dòng)把一段提交表單的客戶(hù)端腳本附加到OnClick中。在客戶(hù)端的OnClick看起來(lái)應(yīng)為下面的形式:

    OnClick="客戶(hù)端代碼;"

這樣ASP.NET自動(dòng)產(chǎn)生的客戶(hù)端腳本會(huì)自動(dòng)附加到“客戶(hù)端代碼;”后不會(huì)產(chǎn)生錯(cuò)誤。

注意

一定不要把“客戶(hù)端代碼;”中的“;”給遺漏了,否則將報(bào)告客戶(hù)端腳本有誤。

下面將介紹Web控件。跟HTML控件相比,Web控件只能是服務(wù)器端控件,因此必須把Web控件的runat屬性設(shè)置為server。另外,聲明Web控件時(shí)必須在類(lèi)型前加上“asp:”命名空間,例如:

    <asp:Button id="Button3"  runat="server" Text="Web 按鈕控件" ToolTip="我是 Web 按鈕控件
"></asp:Button>

提示

命名空間用以保證命名的惟一,同時(shí)也是代碼的邏輯組織形式。

如果需要,還可以設(shè)置Web控件的更多屬性。

注意

Web控件的屬性跟HTML控件的屬性不同,它們用以標(biāo)志服務(wù)器端Web控件自身的狀態(tài),ASP.NET框架會(huì)根據(jù)自身的狀態(tài)繪產(chǎn)生合適的HTML代碼。例如上面的ASPX代碼將產(chǎn)生如下的HTML代碼:

      <input type="submit" name="Button3" value="Web按鈕控件" id="Button3" title="我是
      Web按鈕控件" />

從翻譯可以看出,Button Web按鈕控件被翻譯為一個(gè)類(lèi)型為“submit”的HTML Input元素,控件的ToolTip屬性被翻譯為提交按鈕的Title屬性。

跟服務(wù)器端的HTML控件類(lèi)似,也可以在服務(wù)器端處理Web控件的事件,而該事件是在客戶(hù)端引發(fā)的,例如:

    [Visual Basic]
    <%@ Page language="vb" %>
    <Script runat="server">
      shared  clickcount  as  Integer=0
          Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
            clickcount+=1
            Response.Write(clickcount)
        End Sub
    </Script>
    <html>
    <title>演示W(wǎng)eb控件</title>
    <body>
      <form runat="server">
          <asp:Button id="Button1"
              OnClick="Button1_Click"
            runat="server"
              Text="Web按鈕控件"
              ToolTip="我是Web按鈕控件"/>
      </form>
    </body>
    </html>
    [C#]
    <%@ Page language="cs" %>
    <Script runat="server">
      static int clickcount =0;
      private void Button1_Click(object sender, System.EventArgs e)
      {
        clickcount++;
        Response.Write(clickcount);
      }
    </Script>
    <html>
    <title>演示W(wǎng)eb控件</title>
    <body>
      <form runat="server">
          <asp:Button id="Button1"
              OnClick="Button1_Click"
            runat="server"
              Text="Web按鈕控件"
              ToolTip="我是Web按鈕控件"/>
      </form>
    </body>
    </html>

上述代碼的執(zhí)行結(jié)果如圖2-2所示。這時(shí)單擊窗體上的按鈕,數(shù)字將不斷增大。

圖2-2 執(zhí)行結(jié)果

說(shuō)明

(1)示例代碼中的第三行聲明一個(gè)靜態(tài)變量(也就是為.aspx頁(yè)面對(duì)應(yīng)的Web窗體類(lèi)添加了一個(gè)靜態(tài)成員)。注意,不能在<%…%>之間聲明靜態(tài)成員,只能在服務(wù)端的腳本塊中聲明。

(2)通過(guò)把事件處理的方法直接賦值給Web控件的“On事件”屬性,可以在服務(wù)器端處理服務(wù)控件的事件。

除此之外,下面的代碼也能正確地處理鼠標(biāo)的單擊事件:

    [Visual Basic]
    <%@ Page language="vb" %>
    <Script runat="server">
      shared  clickcount  as  Integer=0
      Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
          clickcount+=1
          Response.Write(clickcount)
      End Sub
      Private Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs)
        AddHandler Button1.Click ,addressof me.Button1_Click
      End Sub
    </Script>
    <html>
    <title>演示W(wǎng)eb控件</title>
    <body>
      <form runat="server">
        <asp:Button id="Button1"
          runat="server"
              Text="Web按鈕控件"
              ToolTip="我是Web按鈕控件"/>
      </form>
    </body>
    </html>

說(shuō)明

Visual Basic.NET中用Addhandler方法將特定的處理方法和控件的事件關(guān)聯(lián)。關(guān)聯(lián)的實(shí)質(zhì)是實(shí)例化一個(gè)委托并將之賦值給控件的某個(gè)事件(不要忘了,在.NET中,事件就是一個(gè)委托變量!)

    [C#]
    <%@ Page language="cs" %>
    <Script runat="server">
      static int clickcount=0  ;
      private void Button1_Click(object sender, System.EventArgs e)
      {
        clickcount++;
          Response.Write(clickcount);
      }
      private void Page_Init(Object sender , System.EventArgs e)
      {
        Button1.Click+=new System.EventHandler(Button1_Click);
      }
    </Script>
    <html>
    <title>演示W(wǎng)eb控件</title>
    <body>
        <form runat="server">
        <asp:Button id="Button1"
          runat="server"
          Text="Web按鈕控件"
          ToolTip="我是Web按鈕控件"/>
        </form>
    </body>
    </html>

說(shuō)明

C#用“+=”把控件事件和處理代碼掛鉤。請(qǐng)注意,默認(rèn)情況下Web窗體的AutoEventWireup屬性為T(mén)rue,這時(shí),頁(yè)面的Init事件發(fā)生時(shí),會(huì)自動(dòng)調(diào)用Page_Init方法。如果指定頁(yè)面的AutoEventWireup的屬性為False,那么必須如下修改代碼:

                      [Visual Basic]
                      <%@ Page language="vb" AutoEventWireup="false"%>
                      …
                      Private  Sub  Page_Init(ByVal  sender  As  System.Object,  ByVal  e  As
                  System.EventArgs) Handles MyBase.Init
                          AddHandler Button1.Click ,addressof me.Button1_Click
                      End Sub
                      評(píng)注:Visual Basic.NET允許用Handlers關(guān)鍵字將處理代碼和事件直接掛鉤。
                      [C#]
                      <%@ Page language="cs" AutoEventWireup="false"%>
                      …
                      override protected void OnInit(EventArgs e)
                      {
                            Button1.Click+=new System.EventHandler(Button1_Click);
                      }

說(shuō)明

當(dāng)Web頁(yè)面被創(chuàng)建時(shí),Web窗體的Init事件被引發(fā)。引發(fā)后實(shí)際上是調(diào)用OnInit方法,OnInit方法又會(huì)通過(guò)代理調(diào)用具體的事件處理代碼。

2.2 排除錯(cuò)誤

因?yàn)槿鄙僦悄艽a提示,編寫(xiě)單文件的ASP.NET應(yīng)用時(shí)發(fā)生錯(cuò)誤更是難免。不過(guò)ASP.NET框架本身為排除.aspx文件中的編碼錯(cuò)誤提供了很好的支持。動(dòng)態(tài)編譯.aspx文件時(shí)發(fā)生編譯錯(cuò)誤,都會(huì)返回給調(diào)用者,并給出排除錯(cuò)誤的建議。

請(qǐng)建立具有下面內(nèi)容的.aspx文件:

            [Visual Basic]
            <%@Page language="vb"AutoEventWireup="true"%>
            <Script runat="server">
              Private Sub Page_Load(ByVal sender As System.Object,ByVal e As System.EventArgs)
                if not IsPostBack then
              Label1.Text=System.Now.ToString("f")
                end if
              End Sub
            </Script>
            <html>
            <title>演示排除錯(cuò)誤</title>
            <body>
            <form runat="server">
                <asp:Label id="Label1" runat=server/>
            </form>
            </body>
            </html>
            [C#]
    <%@ Page language="cs" AutoEventWireup="true"%>
    <Script runat="server">
      private void Page_Load(object sender, System.EventArgs e)
      {
        // 在此處放置用戶(hù)代碼以初始化頁(yè)面
        if(! IsPostBack)
        {
            Label1.Text=System.Now.ToString("f");
        }
      }
    </Script>
    <html>
    <title>演示排除錯(cuò)誤</title>
    <body>
        <form runat="server">
            <asp:Label id="Label1" runat=server/>
        </form>
    </body>
    </html>

上述代碼的本意是在標(biāo)簽上顯示服務(wù)器上的當(dāng)前時(shí)間。但是Now應(yīng)是System.DateTime對(duì)象的屬性,而不是System的屬性,這樣當(dāng)在瀏覽器上請(qǐng)求該窗體時(shí),將獲得編譯錯(cuò)誤信息,如圖2-3所示。

圖2-3 編譯錯(cuò)誤提示信息

提示

在圖2-3中單擊【顯示詳細(xì)的編譯器輸出】按鈕,可以了解.aspx文件被動(dòng)態(tài)編譯的細(xì)節(jié),譬如引用了哪些程序集,動(dòng)態(tài)生成的程序集保存的位置等。在圖2-3中單擊【顯示完整的編譯源】按鈕,還可以查看ASP.NET根據(jù).aspx文件動(dòng)態(tài)產(chǎn)生的源代碼文件,如圖2-4所示。

圖2-4 根據(jù).aspx文件動(dòng)態(tài)產(chǎn)生的源代碼

從圖2-4可以清楚地看出,.aspx文件被轉(zhuǎn)化為一個(gè)System.Web.UI.Page派生類(lèi)。

圖2-4中的錯(cuò)誤提示信息指出了發(fā)生錯(cuò)誤的源代碼所在的位置,給出了解決該錯(cuò)誤的建議方法,這樣排除錯(cuò)誤就很容易了。用System.DateTime.Now替換“System.Now”,就修正了錯(cuò)誤,然后刷新請(qǐng)求,將會(huì)出現(xiàn)如圖2-5所示的正確結(jié)果。

圖2-5 排除錯(cuò)誤后獲得正確結(jié)果

提示

單文件窗體的一個(gè)好處是修改.aspx文件后,不用編譯,再次請(qǐng)求該頁(yè),就能看到更新的結(jié)果。

排除錯(cuò)誤的另外一個(gè)可用的強(qiáng)大工具就是ASP.NET跟蹤,通過(guò)將@Page指令的Trace屬性設(shè)置為true就可以啟用跟蹤:

    [Visual Basic]
    <%@ Page language="vb" AutoEventWireup="true" Trace="true"%>
    [C#]
    <%@ Page language="cs" AutoEventWireup="true" Trace="true"%>

啟用跟蹤后,ASP.NET在響應(yīng)每個(gè)請(qǐng)求時(shí),會(huì)詳細(xì)列出下面的信息:

● 請(qǐng)求詳細(xì)信息

包括會(huì)話(huà)ID、請(qǐng)求類(lèi)型、請(qǐng)求的時(shí)間、狀態(tài)代碼、請(qǐng)求編碼和響應(yīng)編碼,某次請(qǐng)求的詳細(xì)信息如圖2-6所示。

圖2-6 請(qǐng)求詳細(xì)信息

● 跟蹤信息

所有Trace.Write方法輸出的信息都在這兒列出,ASP.NET框架預(yù)先在Page_Init等方法中加入了Trace.Write調(diào)用輸出以輸出跟蹤信息,如圖2-7所示。

圖2-7 跟蹤信息

● 控件樹(shù)

詳細(xì)列出了Web窗體頁(yè)面上的各種控件及父子關(guān)系,如圖2-8所示。

圖2-8 控件樹(shù)

● 標(biāo)頭集合

列出了服務(wù)器返回給客戶(hù)的Header(標(biāo)頭)信息,如圖2-9所示。

圖2-9 標(biāo)頭集合

● 服務(wù)器變量

列出服務(wù)器端的所有變量,如圖2-10所示。

圖2-10 服務(wù)器變量

上述信息能幫助開(kāi)發(fā)人員全面地了解在一次Web窗體請(qǐng)求過(guò)程中所發(fā)生的事情的所有細(xì)節(jié),當(dāng)然也是排除錯(cuò)誤的絕佳輔助工具。

另外,通過(guò)調(diào)用Trace對(duì)象的Write方法,還能將自定義的消息寫(xiě)到跟蹤消息欄中,例如把下面的代碼插入到.aspx文件的Page_Load方法中。

    [Visual Basic]
    <%@ Page language="vb" Trace="true"%>
    <Script runat="server">
        Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs)
            Trace.Write("頁(yè)面事件", "調(diào)試-Page_Load")
        End Sub
    </Script>
    <html>
      <title>演示Trace.Write</title>
    </html>
    [C#]
    <%@ Page language="cs" Trace="true"%>
    <Script runat="server">
      private void Page_Load(object sender, System.EventArgs e)
      {
        Trace.Write("頁(yè)面事件", "調(diào)試-Page_Load");
      }
    </Script>
    <html>
      <title>演示Trace.Write</title>
    </html>

在瀏覽器中請(qǐng)求上述內(nèi)容的.aspx文件,執(zhí)行結(jié)果如圖2-11所示。黑體字突出顯示的代碼的輸出在圖2-11中用方框圈住。

圖2-11 執(zhí)行結(jié)果

如果錯(cuò)誤排除了,需要取消跟蹤,那么將@Page指令的Trace屬性設(shè)置為false即可。

提示

在集成開(kāi)發(fā)環(huán)境下,調(diào)試一個(gè)ASP.NET應(yīng)用跟調(diào)試其他.NET應(yīng)用沒(méi)什么不同,在隱藏代碼文件中設(shè)置斷點(diǎn),然后按【F5】鍵啟動(dòng)調(diào)試。但如果要調(diào)試但文件版本中的腳本,可以用.NET框架提供的CLR調(diào)試器DbgClr.exe,該調(diào)試器位于.NET框架安裝的GuiDebug目錄下。本書(shū)后面將詳細(xì)介紹用DbgClr.exe調(diào)試.aspx頁(yè)面的技術(shù)。

2.3 實(shí)現(xiàn)步驟

有了前面的準(zhǔn)備知識(shí),下面我們將實(shí)現(xiàn)第一個(gè)ASP.NET應(yīng)用的單文件版本的實(shí)現(xiàn)步驟。

2.3.1 第一步:建立Web應(yīng)用目錄

在d:盤(pán)上新建一個(gè)demoasp目錄,然后到【控制面板】上雙擊【管理工具】,雙擊【Internet信息服務(wù)】圖標(biāo),激活I(lǐng)IS管理工具。

右鍵單擊【默認(rèn)Web站點(diǎn)】按鈕,指向【新建】,在彈出的子菜單中單擊【虛擬目錄】按鈕,如圖2-12所示,將激活新建虛擬目錄向?qū)А?/p>

圖2-12 利用關(guān)聯(lián)菜單新建虛擬目錄

按照向?qū)崾荆来卧O(shè)置虛擬目錄的別名(如圖2-13所示)、對(duì)應(yīng)的磁盤(pán)目錄(如圖2-14所示,本例中設(shè)置為d:\demoasp)和虛擬目錄的訪(fǎng)問(wèn)權(quán)限(如圖2-15所示)。

圖2-13 設(shè)置虛擬目錄別名

圖2-14 設(shè)置虛擬目錄對(duì)應(yīng)的磁盤(pán)目錄

圖2-15 設(shè)置虛擬目錄的訪(fǎng)問(wèn)權(quán)限

提示

一個(gè)Web應(yīng)用對(duì)應(yīng)著一個(gè)IIS虛擬目錄,虛擬目錄的別名可以跟對(duì)應(yīng)的磁盤(pán)目錄名不一致。客戶(hù)通過(guò)虛擬目錄別名訪(fǎng)問(wèn)Web應(yīng)用。假設(shè)服務(wù)器diana上有別名為demoASP的虛擬目錄對(duì)應(yīng)到磁盤(pán)目錄d:\demo,而磁盤(pán)目錄demo下有文件default.aspx,那么為了訪(fǎng)問(wèn)該文件,可以在瀏覽器請(qǐng)求地址欄中的URL為http://diana/demoASP/default.aspx

2.3.2 第二步:創(chuàng)建登錄的.aspx文件

文件版本的登錄窗體文件為login.aspx,位于d:\demoasp目錄下,其內(nèi)容如下:

    [Visual Basic]
    <%@ Page Language="vb" %>
    <Script runat=server>
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
          If FormsAuthentication.Authenticate(username.Text, pwd.Value) Then
              FormsAuthentication.RedirectFromLoginPage(username.Text, True)
          Else
                Response.Redirect("login.aspx")
            End If
        End Sub
    </Script>
    <HTML>
        <HEAD>
            <title>請(qǐng)輸入用戶(hù)名和口令WebForm1</title>
        </HEAD>
        <body >
            <form  runat="server">
                <table border=0 align=center width=400>
                    <tr>
                      <td width=150>
                    <asp:label id="Label1"  runat="server">用戶(hù)名</asp:label>
                      </td>
                    <td width=200>
                  <asp:TextBox id="username" runat="server"></asp:TextBox>
                    </td>
                    <td width=50>
                      <asp:RequiredFieldValidator  id="RequiredFieldValidator1"    runat=
"server" ErrorMessage="用戶(hù)名不能為空" ControlToValidate="username" Display="Dynamic">*
</asp:RequiredFieldValidator>
                    </td>
                  </tr>
                  <tr>
                    <td>
                      <asp:label id="Label2"  runat="server">口令</asp:label>
                    </td>
                    <td>
                  <INPUT id="pwd"  type="password"name="Password1"runat="server">
                    </td>
                    <td>
                      <asp:RequiredFieldValidator           id="RequiredFieldValidator2"
runat="server" ErrorMessage="用戶(hù)名不能為空" ControlToValidate="pwd" Display="Dynamic">
*</asp:RequiredFieldValidator>
                    </td>
                  </tr>
                    <tr>
                      <td></td>
                      <td align=center>
                    <asp:Button   id="Button1"     runat="server"   Text="  提  交  "
OnClick="Button1_Click"></asp:Button>
                  </td>
                  <td></td>
                    </tr>
                    <tr>
                      <td></td>
                        <td width=400>
                          <asp:ValidationSummary  id="ValidationSummary1"   runat="serv
    ></asp:ValidationSummary>
                        </td>
                      <td?</td>
                    </tr>
                </table>
            </form>
        </body>
    </HTML>
    [C#]
    <%@ Page Language="cs" %>
    <Script runat=server>
            private void Button1_Click(object sender, System.EventArgs e)
            {
                if( FormsAuthentication.Authenticate(username.Text, pwd.Value))
                {
                    FormsAuthentication.RedirectFromLoginPage(username.Text, true);
                }
                            else
                    Response.Redirect("login.aspx");
                }
    </Script>

其他代碼跟編程語(yǔ)言為Visual Basic時(shí)相同,省略…

提示

利用<table></table>元素幫助對(duì)其控件。<tr></tr>表示定義一行,<td></td>表示定義一列。

繼續(xù)創(chuàng)建默認(rèn)的窗體default.aspx,其實(shí)現(xiàn)代碼如下所示:

    [Visual Basic]
    <%@ Page Language="vb" %>
    <Script runat=server>
          Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs)
          If Not IsPostBack Then
                      Label1.Text=User.Identity.Name&",歡迎光臨"
          End If
          End Sub
          Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
          FormsAuthentication.SignOut()
          End Sub
    </Script>
    <HTML>
                <HEAD>
                    <title>請(qǐng)輸入用戶(hù)名和口令WebForm1</title>
                </HEAD>
                <body >
                    <form  runat="server">
                      <table border=0 align=center width=400>
                        <td width=300>
                            <asp:Label id="Label1" runat="server" >歡迎光臨</asp:Label>
                        </td>
                        <td>
                           <asp:Button    id="Button1"    runat="server"       Text="Sign    Out"
        OnClick="Button1_Click"></asp:Button>
                        </td>
                      </table>
                    </form>
                </body>
    </HTML>
    [C#]
    <%@ Page Language="cs" %>
    <Script runat=server>
                    private void Page_Load(object sender, System.EventArgs e)
                    {
                        if(!IsPostBack)
                        Label1.Text = User.Identity.Name + ",歡迎光臨";
                    }
                        private void Button1_Click(object sender, System.EventArgs e)
                    {
                        FormsAuthentication.SignOut();
                    }
    </Script>

下面的代碼跟語(yǔ)言為Visual Basic時(shí)相同。

2.3.3 第三步:編寫(xiě)配置文件

在demoasp目錄下新建一個(gè)web.config文件,其內(nèi)容如下:

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
      <system.web>
          <authentication mode="Forms">
            <forms loginURL="login.aspx">
              <credentials passwordFormat = "Clear" >
                  <user name="小楊" password="5157"/>
                  <user name="曉華" password="1234"/>
              </credentials>
                  </forms>
                  </authentication>
                  <authorization>
          <deny users="?,曉華"/>
          <allow users="*" />
                  </authorization>
      </system.web>
    </configuration>

配置文件中的第一行XML序言不可省略,否則將報(bào)告配置文件中無(wú)效的字符,如圖2-16所示。

圖2-16 配置錯(cuò)誤

2.3.4 第四步:測(cè)試

直接在瀏覽器下輸入http://diana/demoasp/default.aspx會(huì)自動(dòng)導(dǎo)入到登錄畫(huà)面。在登錄畫(huà)面中的用戶(hù)名中輸入“小楊”,口令中輸入“5157”,再單擊【提交】按鈕則會(huì)成功導(dǎo)入default.aspx畫(huà)面。如果登錄畫(huà)面輸入了其他用戶(hù),則不需離開(kāi)登錄畫(huà)面而直接進(jìn)入default.aspx畫(huà)面。

2.3.5 第五步:部署

把login.aspx、default.aspx和web.config文件拷貝到目標(biāo)服務(wù)器某個(gè)虛擬目錄對(duì)應(yīng)的磁盤(pán)目錄下,就完成了在發(fā)行服務(wù)器上的部署。這個(gè)過(guò)程中沒(méi)有涉及到任何程序集。

提示

如果.aspx窗體用到了自動(dòng)編譯過(guò)程中沒(méi)有自動(dòng)添加對(duì)其引用的程序集,則應(yīng)該把這些程序集也復(fù)制到目標(biāo)服務(wù)器Web應(yīng)用的bin子目錄下。

2.3.6 第六步:開(kāi)發(fā)單文件版本的ASP.NET應(yīng)用

如果已有Visual Studio.NET工具,則可以用它來(lái)簡(jiǎn)化單文件窗體的設(shè)計(jì)。按照下面介紹的方法,可以把一個(gè)具有隱藏代碼文件的窗體輕松地轉(zhuǎn)化為一個(gè)單文件窗體。

● 新建一個(gè)Web窗體,新建的窗體為Webform3。

● 利用Web窗體設(shè)計(jì)器設(shè)計(jì)窗體,設(shè)計(jì)好的Web窗體如圖2-17所示。

圖2-17 設(shè)計(jì)好的Web窗體

設(shè)計(jì)好的界面最上邊是一個(gè)廣告控件AdRotatorl,下面是一個(gè)HTML表格Table控件。表格的第一行依次為HTML標(biāo)簽控件、Web文本框控件和Web必須域驗(yàn)證控件,它驗(yàn)證的控件是文本框;表格的第二行中間是Web按鈕控件;表格第三行是Web驗(yàn)證匯總控件。

● 編寫(xiě)代碼

一般可以為界面元素添加事件處理的代碼,譬如添加“Go!”按鈕的單擊事件的響應(yīng),或添加一些公共的方法:

    [Visual Basic]
        Sub PageSub(ByVal para As Object)
        End Sub
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
        Handles Button1.Click
          '添加處理事件單擊的代碼
        End Sub
    [C#]
          void PageSub(object para)
          {
          }
        private void Button1_Click(object sender, System.EventArgs e)
          {
          }

提示

除此之外,隱藏代碼文件還有Web窗體設(shè)計(jì)器自動(dòng)產(chǎn)生的代碼,以及在新建一個(gè)Web窗體時(shí)自動(dòng)產(chǎn)生的代碼。

● 實(shí)施轉(zhuǎn)化

修改.aspx文件的第一行,修改后的代碼看起來(lái)應(yīng)如下所示:

    [Visual Basic]
    <%@ Page language="vb" AutoEventWireup="false" %>
    [C#]
    <%@ Page language="c#" AutoEventWireup="false" %>

然后在.aspx文件的第三行新加如下的代碼塊:

    <Script runat=server>
    </Script>

接下來(lái),把隱藏代碼文件中的實(shí)現(xiàn)Web頁(yè)類(lèi)的代碼拷貝到<Script></Script>代碼塊內(nèi),注意,那些跟界面元素相關(guān)的變量聲明,以及類(lèi)本身的聲明不用拷貝。若編程語(yǔ)言為Visual Basic,則要對(duì)拷貝后的代碼做進(jìn)一步的處理,即修改跟處理界面元素事件相關(guān)的代碼:

(1)去掉事件處理代碼方法聲明中的Handers關(guān)鍵字及其以后的代碼,例如,把:

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles
Button1.Click

修改為:

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)

(2)在Page_Init方法的最后,手工將事件處理代碼和界面控件的事件掛鉤,例如在Page_Init的最后添加下面的代碼:

    AddHandler Button1.Click, AddressOf Button1_Click

根據(jù)隱藏代碼合成的單文件Web窗體文件最后看起來(lái)如下所示:

    [Visual Basic]
    <%@ Page Language="vb" AutoEventWireup="false" %>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
    <!--下面的代碼直接從隱藏代碼中拷貝而來(lái) -->
    <Script runat="server">
      #Region"Web 窗體設(shè)計(jì)器生成的代碼 "
        '該調(diào)用是 Web 窗體設(shè)計(jì)器所必需的。
        <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
        End Sub
        Private Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles
        MyBase.Init
          'CODEGEN: 此方法調(diào)用是 Web 窗體設(shè)計(jì)器所必需的。
          '不要使用代碼編輯器修改它。
          InitializeComponent()
          '添加的代碼,手工掛鉤事件
          AddHandler Button1.Click, AddressOf Button1_Click
        End Sub
    #End Region
        Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs)
        Handles MyBase.Load
          '在此處放置初始化頁(yè)的用戶(hù)代碼
        End Sub
        Sub PageSub(ByVal para As Object)
        End Sub
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
          '添加處理事件單擊的代碼
        End Sub
    </Script>
    <HTML>
                <HEAD>
                        <title>WebForm3</title>
                        <meta name="GENERATOR"content="Microsoft Visual Studio.NET 7.0">
                        <meta name="CODE_LANGUAGE"content="Visual Basic 7.0">
                        <meta name="vs_defaultClientScript"content="JavaScript">
                        <meta                                                 name="vs_targetSchema"
        content="http://schemas.microsoft.com/intellisense/ie5">
                </HEAD>
                <body MS_POSITIONING="GridLayout">
                        <form id="Form1"method="post"runat="server">
                        <FONT face="宋體">
                        <TABLE id="Table2" style="Z-INDEX: 101; LEFT: 50px; WIDTH: 300px;
        POSITION: absolute; TOP: 94px; HEIGHT: 86px" cellSpacing="1" cellPadding="1" width="300"
        border="0">
                            <TR>
                                        <TD style="WIDTH:152px;HEIGHT:30px">
                                        <DIV style="DISPLAY: inline; WIDTH: 146px; HEIGHT:
        31px"ms_positioning="FlowLayout">輸入查詢(xún)條件</DIV>
                                        </TD>
                                        <TD style="HEIGHT:30px">
                                        <asp:TextBox                                  id="TextBox1"
        runat="server"></asp:TextBox></TD>
                                        <TD style="HEIGHT:30px">
                                        <asp:RequiredFieldValidator id="RequiredFieldValidator1"
        runat="server"  ErrorMessage=" 查 詢(xún) 條 件 不 能 為 空 "  ControlToValidate="TextBox1">*
        </asp:RequiredFieldValidator></TD>
                            </TR>
                            <TR>
                                        <TD style="WIDTH:152px"></TD>
                                        <TD>
                                        <asp:Button  id="Button1"         runat="server"  Text="Go!"
        Width="121px"></asp:Button></TD>
                                        <TD></TD>
                            </TR>
                            <TR>
                                        <TD style="WIDTH:152px"></TD>
                                        <TD>
                                        <asp:ValidationSummary      id="ValidationSummary1"
        runat="server"></asp:ValidationSummary></TD>
                                        <TD></TD>
                            </TR>
                        </TABLE>
                        <asp:AdRotator  id="AdRotator1"  style="Z-INDEX:          102;  LEFT:  32px;
        POSITION:    absolute;   TOP:   11px"   runat="server"        Width="425px"   Height="60px"
        AdvertisementFile="XMLFile1.xml"BackColor="CornflowerBlue"></asp:AdRotator>
                        </FONT>
                        </form>
                </body>
    </HTML>
    [C#]
    <%@ Page language="c#" AutoEventWireup="false" %>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
    <!--下面的代碼直接從隱藏代碼中拷貝而來(lái) -->
    <Script runat=server >
                        private void Page_Load(object sender,System.EventArgs e)
                        {
                        // 在此處放置用戶(hù)代碼以初始化頁(yè)面
                        }
                        #region Web Form Designer generated code
                        override protected void OnInit(EventArgs e)
                        {
                        //
                        //CODEGEN:該調(diào)用是 ASP.NET Web 窗體設(shè)計(jì)器所必需的。
                        //
                        InitializeComponent();
                        base.OnInit(e);
                        }
                        ///<summary>
                        /// 設(shè)計(jì)器支持所需的方法 - 不要使用代碼編輯器修改
                        /// 此方法的內(nèi)容。
                        ///</summary>
                        private void InitializeComponent()
                        {
                        this.Button1.Click+=new System.EventHandler(this.Button1_Click);
                        this.Load+=new System.EventHandler(this.Page_Load);
                        }
                        #endregion
                        void PageSub(object para)
                        {
                        }
                private void Button1_Click(object sender,System.EventArgs e)
                        {
                        }
    </Script>
    <HTML>
                <HEAD>
                        <title>WebForm3</title>
                        <meta name="GENERATOR"Content="Microsoft Visual Studio 7.0">
                        <meta name="CODE_LANGUAGE"Content="C#">
                        <meta name="vs_defaultClientScript"content="JavaScript">
                        <meta                                                 name="vs_targetSchema"
        content="http://schemas.microsoft.com/intellisense/ie5">
                </HEAD>
                <body MS_POSITIONING="GridLayout">
                        <FORM id="Form1"method="post"runat="server">
                        <FONT face="宋體">
                        <asp:AdRotator  id="AdRotator1"  style="Z-INDEX:          102;  LEFT:  41px;
        POSITION: absolute; TOP: 11px" runat="server" Width="425px" AdvertisementFile="XMLFile1.xml"
        Height="60px"BackColor="CornflowerBlue"></asp:AdRotator>
                        <TABLE id="Table2" style="Z-INDEX: 103; LEFT: 53px; WIDTH: 300px;
        POSITION: absolute; TOP: 108px; HEIGHT: 86px" cellSpacing="1" cellPadding="1" width="300"
        border="0">
                            <TR>
                                        <TD style="WIDTH:152px;HEIGHT:30px">
                                        <DIV style="DISPLAY: inline; WIDTH: 146px; HEIGHT:
        31px"ms_positioning="FlowLayout">輸入查詢(xún)條件</DIV>
                                        </TD>
                                        <TD style="HEIGHT:30px">
                                        <asp:TextBox                                  id="TextBox1"
        runat="server"></asp:TextBox></TD>
                                        <TD style="HEIGHT:30px">
                                        <asp:RequiredFieldValidator id="RequiredFieldValidator2"
        runat="server"  ControlToValidate="TextBox1"  ErrorMessage="  查  詢(xún)  條  件  不  能   為  空
        ">*</asp:RequiredFieldValidator></TD>
                            </TR>
                            <TR>
                                        <TD style="WIDTH:152px"></TD>
                                        <TD>
                                        <asp:Button id="Button1" runat="server" Width="121px"
        Text="Go!"></asp:Button></TD>
                              <TD></TD>
                          </TR>
                          <TR>
                              <TD style="WIDTH:152px"></TD>
                              <TD>
                                  <asp:ValidationSummary      id="ValidationSummary1"
runat="server"></asp:ValidationSummary></TD>
                              <TD></TD>
                          </TR>
                        </TABLE>
                    </FONT>
                </FORM>
        </body>
    </HTML>

好了,借助于Visual Studio.NET,不需要對(duì)ASP.NET語(yǔ)法有多少了解,我們就有了設(shè)計(jì)任意復(fù)雜的單文件窗體的能力。當(dāng)然,為了更好地設(shè)計(jì)Web窗體,對(duì)ASP.NET語(yǔ)法的深入了解是必要的,本書(shū)后續(xù)章節(jié)將在本章的基礎(chǔ)上,進(jìn)一步介紹ASP.NET語(yǔ)法。

2.4 小結(jié)

本章介紹了開(kāi)發(fā)單文件版本的ASP.NET應(yīng)用的全貌。開(kāi)發(fā)單文件版本的ASP.NET應(yīng)用需要更多地了解ASP.NET的語(yǔ)法,并可能會(huì)產(chǎn)生更多的錯(cuò)誤。本章提供了ASP.NET語(yǔ)法的綜述性的介紹,并提供了排除ASP.NET應(yīng)用中BUG的方法。本章的重點(diǎn)仍然是第一個(gè)ASP.NET應(yīng)用的單文件版本的實(shí)現(xiàn)步驟。本章最后還介紹了如何利用Visual Studio.NET來(lái)開(kāi)發(fā)單文件版本的ASP.NET應(yīng)用。

推薦閱讀
  1. 2020年咨詢(xún)工程師(投資)《項(xiàng)目決策分析與評(píng)價(jià)》過(guò)關(guān)必做1200題(含歷年真題)
  2. 2015心理咨詢(xún)師國(guó)家職業(yè)資格考試專(zhuān)用輔導(dǎo)教材(二級(jí)):教材精解(圖解版)+題庫(kù)解析+歷年真題+押題預(yù)測(cè)
  3. CFA一級(jí)中文精講①(第3版)
  4. 人力資源管理專(zhuān)業(yè)知識(shí)與實(shí)務(wù)歷年真題及押題精選試卷
  5. 企業(yè)人力資源管理師(四級(jí))資格考試專(zhuān)用輔導(dǎo)教材
  6. 2019年統(tǒng)計(jì)師《統(tǒng)計(jì)工作實(shí)務(wù)(中級(jí))》復(fù)習(xí)全書(shū)【核心講義+歷年真題詳解】
  7. 2019年口腔執(zhí)業(yè)助理醫(yī)師資格考試歷年真題及詳解
  8. 2019年國(guó)際貨運(yùn)代理《國(guó)際海上貨運(yùn)代理理論與實(shí)務(wù)》章節(jié)練習(xí)題詳解
  9. 2020年兒科主治醫(yī)師考試過(guò)關(guān)必做3000題(含歷年真題)
  10. 新駕考汽車(chē)駕駛速成(適用B1、B2、A1、A2):第2版
  11. 多媒體課件設(shè)計(jì)與制作(視頻指導(dǎo)版)
  12. 2019年全國(guó)導(dǎo)游人員資格考試輔導(dǎo)教材-天津?qū)в畏?wù)能力
  13. 2017年全國(guó)專(zhuān)利代理人資格考試通關(guān)秘籍.專(zhuān)利法律知識(shí)
  14. 2019年初級(jí)會(huì)計(jì)師《經(jīng)濟(jì)法基礎(chǔ)》歷年真題詳解與考前押題試卷
  15. 2019年全國(guó)導(dǎo)游人員資格考試輔導(dǎo)教材-青海導(dǎo)游基礎(chǔ)知識(shí)
主站蜘蛛池模板: 平定县| 泽州县| 五莲县| 闽清县| 金昌市| 丰县| 斗六市| 保康县| 乌拉特中旗| 通榆县| 济南市| 渝北区| 吐鲁番市| 富源县| 喀什市| 前郭尔| 开阳县| 溆浦县| 金山区| 湖南省| 当涂县| 上犹县| 德昌县| 平安县| 铜梁县| 麦盖提县| 西峡县| 巨鹿县| 大城县| 和硕县| 游戏| 兴山县| 娄底市| 巴彦淖尔市| 丹凤县| 庐江县| 西宁市| 思茅市| 多伦县| 苍溪县| 怀柔区|