程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> .NET實例教程 >> ASP.NET WebForm頁面內容輸出方式

ASP.NET WebForm頁面內容輸出方式

編輯:.NET實例教程


這次我們談的話題是“Web Form頁面上輸出內容的方式”。這其實是一個非常舊的話題了,因為本文的內容甚至可以運用於ASP.NET 1.1之上。不過這個話題的適用范圍很廣,因為即使是目前最新的ASP.NET MVC框架,它的默認視圖引擎依舊是基於ASP.NET WebForm的(如Page,Control,MasterPage)。甚至說,由於ASP.NET MVC框架的特性,我們會遇到更多在頁面上“直接輸出”內容的情況。因此,這個話題在ASP.Net MVC應用中可能由為重要。

那麼就拿ASP.Net MVC舉例吧。假如,我們在頁面上生成一個Partial VIEw,我們可以這麼做:

<% Html.RenderPartial("MyPartialVIEw"); %> 

然而,在前一篇文章中我們提出了一個新的方法Partial,它返回一個字符串,它可以在頁面上這樣使用:

<%= Html.Partial("MyPartialVIEw") %>

一個ASPx頁面會被編譯成Page類的一個子類,這個子類的主要“功能”是覆蓋了基類的Render方法:

public class MyPage : Page
{
    protected override void Render(HtmlTextWriter writer)
    {
        ...
    }
}  
我們平時在ASPx頁面中編寫的大量內容,其實都會變成操作writer的代碼。例如使用writer.Write方法輸出內容,或者把writer交給子控件的Render方法用於生成內容。那麼,以上兩種頁面上的標記分別又是如何操作writer的呢?

<%= expression %>

首先是<%= %>標記。<%= %>標記內包含的是一個“表達式”,因此它不能以分號結尾。表達式內部的數據就會直接寫入writer。例如這樣的標記:

<%= DateTime.Now %>

在編譯過後就成為:

writer.Write(DateTime.Now)

與<%= %>標記不同,<% %>標記中間其實包含的是“語句”。語句自然可以有多行,自然每行最後需要有分號,這就像我們平時寫C#代碼那樣。不過實際上,語句的功能其實並不是為了“輸出內容”,而是用來“控制邏輯”。例如,您在頁面上寫了這樣的代碼:

<% Func<int, bool> odd = i => i % 2 != 0; %>

這樣就相當於您在Render方法內部聲明了一個局部變量odd,它的類型是一個Func<int, bool>委托。而如果您編寫這樣的代碼:

<% for (int i = 0; i < 10; i++) { %>
    <span>
        <%= i + 1 %>
    </span>
<% } %>

則生成的Render方法中就會包含:

for (int i = 0; i < 10; i++)
{
    writer.Write("<span>");
    writer.Write(i + 1);
    writer.Write("</span>");
}

如果是寫在頁面上的普通Html標記,編譯後就被當作普通字符串來處理了。有些朋友一直談“客戶端控件”等等,其實如果一個元素上沒有runat="server"標記,ASP.Net只是把它們當作普通字符串處理,並不會有任何“Html元素”的概念。當然,上面的代碼表現的是“意圖”,事實上在編譯過後ASPx頁面中的空格和換行等字符也會包含在輸出的內容中。

那麼,既然<% %>中包含的是用來控制邏輯的語句,本身不是用來表示輸出的,那麼為什麼剛才代碼中的Html.RenderPartial方法也會生成頁面內容呢?那是因為RenderPartial方法直接向當前HttpContext.Response.Output裡寫入字符了。很多朋友經常使用Response.Write來輸出內容,其實在Write方法內部就是輸出到Output中。

事實上,即使我們的頁面中使用了HtmlTextWriter來輸出內容,但它內部也是封裝了Output所暴露出的TextWriter中。為了驗證,您可以在代碼中設置斷點並觀察Render方法的writer參數,在“正常情況下”可以發現writer.InnerWriter屬性是一個HttpWriter對象,這是個TextWriter的子類,也是ASP.Net中定義的內部類型。

這便是ASP.Net頁面輸出的細節。那麼請問,以下兩種輸出方式的區別是什麼呢?

<%= "Hello World" %>
<% Response.Write("Hello World") %>

從效果上看,兩者沒有任何區別。但是實際上前者是使用頁面的HtmlTextWriter對象輸出的,而後者則直接向Response.Output裡輸出內容。這個區別看似不重要,但其實它會涉及到我們很多開發過程中可用的實踐方式。在今後的文章中,我會提出生成頁面內容的一些准則,解釋這些准則的原因,並指出ASP.Net MVC本身是如何破壞這些設計准則的。

自然,修改版本的ASP.Net MVC會發布在MvcPatch項目中。

原文地址:http://www.cnblogs.com/JeffreyZhao/archive/2009/09/16/where-does-ASPnet-page-render-to.Html

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved