共用方式為


多個 ContentPlaceHolders 和預設內容 (C#)

由斯科特· 米切爾

下載 PDF

檢查如何將多個內容位置持有者新增至主版頁面,以及如何在內容位置持有者中指定預設內容。

簡介

在上一個教學課程中,我們已檢查主版頁面如何讓 ASP.NET 開發人員建立一致的全網站版面配置。 主版頁面會定義其所有內容頁面和可逐頁自定義之區域通用的標記。 在上一個教學課程中,我們建立了簡單的主版頁面 (Site.master) 和兩個內容頁面 (Default.aspxAbout.aspx)。 我們的主版頁面由兩個名為 headMainContent的 ContentPlaceHolders 組成,分別位於 <head> 元素和 Web Form 中。 雖然內容頁面各有兩個 Content 控件,但我們只指定對應至 MainContent之內容的標記。

如 中的 Site.master兩個 ContentPlaceHolder 控件所證明,主版頁面可能包含多個 ContentPlaceHolders。 更重要的是,主版頁面可能會指定 ContentPlaceHolder 控件的預設標記。 然後,內容頁面可以選擇性地指定自己的標記或使用預設標記。 在本教學課程中,我們將探討如何在主版頁面中使用多個內容控件,並瞭解如何在 ContentPlaceHolder 控件中定義預設標記。

步驟 1:將其他 ContentPlaceHolder 控件新增至主版頁面

許多網站設計都包含螢幕上的數個區域,這些區域會逐頁自定義。 Site.master,我們在上一個教學課程中建立的主版頁面,在名為 MainContent的Web窗體中包含單一 ContentPlaceHolder。 具體而言,此 ContentPlaceHolder 位於 元素內mainContent<div>

圖 1 顯示 Default.aspx 透過瀏覽器檢視時。 以紅色圈圈的區域是對應至 MainContent的頁面特定標記。

圓形區域會顯示目前可逐頁自定義的區域

圖 01:圓形區域顯示目前可逐頁自訂的區域(單擊以檢視完整大小的影像

假設除了圖 1 中顯示的區域之外,我們也需要在 [課程與新聞] 區段下方的左側數據行中新增頁面特定專案。 為了達成此目的,我們會將另一個 ContentPlaceHolder 控件新增至主版頁面。 若要跟著操作,請在 Visual Web Developer 中開啟 Site.master 主版頁面,然後在 [新聞] 區段之後,將 ContentPlaceHolder 控件從 [工具箱] 拖曳到設計工具上。 將 ContentPlaceHolder 的 ID 設定為 LeftColumnContent

將 ContentPlaceHolder 控制項新增至主版頁面的左欄

圖 02:將 ContentPlaceHolder 控件新增至主版頁面的左欄 (按兩下以檢視完整大小的影像

藉由將 ContentPlaceHolder 新增 LeftColumnContent 至主版頁面,我們可以藉由在設定為 的頁面中包含 ContentPlaceHolderID LeftColumnContentContent 控件,以逐頁方式定義此區域的內容。 我們會在步驟 2 中檢查此程式。

步驟 2:在內容頁面中定義新 ContentPlaceHolder 的內容

將新的內容頁面新增至網站時,Visual Web Developer 會自動為所選主版頁面中的每個 ContentPlaceHolder 在頁面中建立內容控件。 在步驟 1 中 LeftColumnContent 將 ContentPlaceHolder 新增至主版頁面之後,新的 ASP.NET 頁面現在會有三個內容控件。

為了說明這一點,請將新的內容頁面新增至系結至Site.master主版頁面的MultipleContentPlaceHolders.aspx根目錄。 Visual Web Developer 會使用下列宣告式標記來建立此頁面:

<%@ Page Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true" CodeFile="MultipleContentPlaceHolders.aspx.cs" Inherits="MultipleContentPlaceHolders" Title="Untitled Page" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" Runat="Server">
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="LeftColumnContent" Runat="Server">
</asp:Content>

在參考 MainContent ContentPlaceHolders (Content2) 的內容控件中輸入一些內容。 接下來,將下列標記新增至 Content3 Content 控件(參考 LeftColumnContent ContentPlaceHolder):

<h3>Page-Specific Content</h3>
<ul>
 <li>This content is defined in the content page.</li>
 <li>The master page has two regions in the Web Form that are editable on a
 page-by-page basis.</li>
</ul>

新增此標記之後,請透過瀏覽器瀏覽頁面。 如圖 3 所示,放置於內容控件中的 Content3 標記會顯示在新聞區段下方的左欄中(以紅色圓圈)。 放置在 中的 Content2 標記會顯示在頁面的右部分(以藍色圓圈)。

左欄現在包含新聞區段下方的頁面特定內容

圖 03:左欄現在包含新聞區段下方的頁面特定內容(按兩下以檢視完整大小的影像

定義現有內容頁面中的內容

建立新的內容頁面會自動納入我們在步驟 1 中新增的 ContentPlaceHolder 控件。 但是,我們的兩個現有內容頁面 - About.aspxDefault.aspx - 沒有 ContentPlaceHolder 的內容控制件 LeftColumnContent 。 若要在這兩個現有頁面中指定此 ContentPlaceHolder 的內容,我們必須自行新增 Content 控件。

與大部分 ASP.NET Web 控制件不同,Visual Web 開發人員工具箱不包含內容控制項專案。 我們可以將內容控件的宣告式標記手動輸入至 [來源] 檢視,但更簡單且更快速的方法就是使用 [設計] 檢視。 About.aspx開啟頁面並切換至 [設計] 檢視。 如圖 4 所示, LeftColumnContent ContentPlaceHolder 會出現在 [設計] 檢視中;如果您將滑鼠移至該檢視上,顯示的標題會顯示:「LeftColumnContent (Master)。標題中包含 「Master」 表示此 ContentPlaceHolder 頁面沒有定義任何 Content 控制件。 如果 ContentPlaceHolder 有 Content 控件,如同 的案例 MainContent,標題會讀取:「ContentPlaceHolderID (自定義)。」

若要將 ContentPlaceHolder 的內容控件 LeftColumnContent 新增至 About.aspx,請展開 ContentPlaceHolder 的智慧標記,然後按兩下 [建立自定義內容] 連結。

About.aspx的設計檢視會顯示 LeftColumnContent ContentPlaceHolder

圖 04:顯示 LeftColumnContent ContentPlaceHolder 的設計檢視About.aspx按兩下以檢視完整大小的影像

點選 「建立自訂內容」 連結會在頁面中產生必要的 [內容] 控制件,並將其 屬性設定 ContentPlaceHolderID 為 ContentPlaceHolder 的 ID。 例如,按兩下列的About.aspxLeftColumnContent區域自訂內容】 連結,會將下列宣告式標記新增至頁面:

<asp:Content ID="Content3" runat="server" contentplaceholderid="LeftColumnContent">
 
</asp:Content>

省略內容控制件

ASP.NET 不需要所有內容頁面都包含主版頁面中定義之每個 ContentPlaceHolder 的內容控制件。 如果省略 Content 控件,ASP.NET 引擎會使用主版頁面中 ContentPlaceHolder 內定義的標記。 此標記稱為 ContentPlaceHolder 的預設內容,而且在某些區域的內容 在大部分頁面中很常見,但需要針對少量頁面自定義。 步驟 3 會探索在主版頁面中指定預設內容。

目前,Default.aspx包含和 MainContent ContentPlaceHolders 的兩個 Content 控件head;它沒有 的內容LeftColumnContent控制項。 因此,轉譯 LeftColumnContent ContentPlaceHolder Default.aspx 的預設內容時會使用。 由於我們尚未為此 ContentPlaceHolder 定義任何預設內容,因此凈效果是此區域不會發出任何標記。 若要確認此行為,請瀏覽 Default.aspx 瀏覽器。 如圖 5 所示,新聞區段下方的左側數據行中不會發出任何標記。

LeftColumnContent ContentPlaceHolder 未轉譯任何內容

圖 05:ContentPlaceHolder 未轉譯 LeftColumnContent 任何內容(按兩下以檢視完整大小的影像

步驟 3:在主版頁面中指定預設內容

某些網站設計包含一個區域,其內容與網站中所有頁面的內容相同,但一或兩個例外狀況除外。 請考慮支援用戶帳戶的網站。 這類網站需要登入頁面,訪客可以輸入其認證來登入網站。 為了加速登入程式,網站設計工具可能會在每個頁面左上角包含使用者名稱和密碼文本框,以允許使用者登入,而不需要明確流覽登入頁面。 雖然這些使用者名稱和密碼文本框在大部分頁面中都很有用,但它們在登入頁面中是多餘的,這已經包含使用者認證的文本框。

若要實作此設計,您可以在主版頁面左上角建立 ContentPlaceHolder 控件。 每個需要在其左上角顯示使用者名稱和密碼文本框的頁面,都會為此 ContentPlaceHolder 建立內容控制件,並新增必要的介面。 另一方面,登入頁面會省略為此 ContentPlaceHolder 新增 Content 控件,或建立未定義標記的內容控件。 這種方法的缺點是,我們必須記得將使用者名稱和密碼文本框新增至我們新增至網站的每個頁面(登入頁面除外)。 這要求麻煩。 我們可能忘記將這些文本框新增至頁面或兩個或更糟的是,我們可能不會正確實作介面(也許只新增一個文本框,而不是兩個文本框)。

更好的解決方案是將使用者名稱和密碼文本框定義為 ContentPlaceHolder 的預設內容。 如此一來,我們只需要在未顯示使用者名稱和密碼文本框的少數頁面中覆寫此默認內容(例如登入頁面)。 為了說明指定 ContentPlaceHolder 控件的預設內容,讓我們實作剛才討論的案例。

注意

本教學課程的其餘部分會更新網站,以在所有頁面的左側數據行中包含登入介面,但登入頁面。 不過,本教學課程不會檢查如何設定網站以支援用戶帳戶。 如需本主題的詳細資訊,請參閱我的 窗體驗證、授權、用戶帳戶和角色 教學課程。

新增 ContentPlaceHolder 並指定其預設內容

開啟主版頁面,並將 Site.master 下列標記新增至標籤和 Lessons 區段之間的 DateDisplay 左側資料行:

<asp:ContentPlaceHolder ID="QuickLoginUI" runat="server">
 <asp:Login ID="QuickLogin" runat="server" 
    TitleText="<h3>Sign In</h3>"
    FailureAction="RedirectToLoginPage">
 </asp:Login>
</asp:ContentPlaceHolder>

新增此標記之後,主版頁面的設計檢視看起來應該類似圖 6。

主版頁面包含登入控件

圖 06:主版頁面包含登入控制項(按兩下以檢視完整大小的影像

此 ContentPlaceHolder QuickLoginUI具有 Login Web 控件做為其預設內容。 [登入] 控制項會顯示使用者介面,提示使用者輸入使用者的使用者名稱和密碼,以及 [登入] 按鈕。 按兩下 [登入] 按鈕時,登入控件會在內部針對成員資格 API 驗證使用者的認證。 若要在實務上使用此登入控件,您必須將月臺設定為使用成員資格。 本主題超出本教學課程的範圍;如需建置支援使用者帳戶的 Web 應用程式的詳細資訊,請參閱我的 窗體驗證、授權、用戶帳戶和角色 教學課程。

您可以隨意自定義登入控件的行為或外觀。 我已設定其兩個屬性: TitleTextFailureActionTitleText預設值為 「Log In」 的屬性值會顯示在控件的使用者介面頂端。 我已設定這個屬性,讓它將文字「登入」 <h3> 顯示為元素。 屬性 FailureAction 會指出如果使用者的認證無效,該怎麼辦。 它預設為 的值 Refresh,此值會將使用者保留在相同的頁面上,並在 [登入] 控件內顯示失敗訊息。 我已將它變更為 RedirectToLoginPage,這會在認證無效的情況下,將用戶傳送至登入頁面。 我偏好在用戶嘗試從其他頁面登入時,將用戶傳送至登入頁面,但失敗,因為登入頁面可以包含其他指示和選項,而無法輕易放入左側數據行。 例如,登入頁面可能包含擷取忘記密碼或建立新帳戶的選項。

建立登入頁面並覆寫默認內容

完成主版頁面后,下一個步驟是建立登入頁面。 將 ASP.NET 頁面新增至您網站的根目錄,並將 Login.aspx它系結至 Site.master 主版頁面。 這樣做會建立一個包含四個 Content 控件的頁面,其中一個用於 中 Site.master定義的 ContentPlaceHolders。

將登入控件新增至 MainContent 內容控制件。 同樣地,您可以隨意將任何內容新增至 LeftColumnContent 區域。 不過,請務必將 ContentPlaceHolder 的內容控件 QuickLoginUI 保留空白。 這可確保登入控件不會出現在登入頁面的左欄中。

定義 和 LeftColumnContent 區域的內容MainContent之後,登入頁面的宣告式標記看起來應該如下所示:

<%@ Page Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true" CodeFile="Login.aspx.cs" Inherits="Login" Title="Untitled Page" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" Runat="Server">
 <h2>
 Sign In</h2>
 <p>
 <asp:Login ID="Login1" runat="server" TitleText="">
 </asp:Login>
 </p>
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="QuickLoginUI" Runat="Server">
</asp:Content>
<asp:Content ID="Content4" ContentPlaceHolderID="LeftColumnContent" Runat="Server">
 <h3>Sign In Tasks</h3>
 <ul>
 <li>Create a New Account</li>
 <li>Recover Forgotten Password</li>
 </ul>
 <p>TODO: Turn the above text into links...</p>
</asp:Content>

圖 7 顯示透過瀏覽器檢視此頁面。 因為此頁面會指定 ContentPlaceHolder 的內容控制件 QuickLoginUI ,所以它會覆寫主版頁面中指定的預設內容。 淨效果是主版頁面設計檢視中顯示的登入控件(請參閱圖 6)未在此頁面轉譯。

登入頁面會壓縮 QuickLoginUI ContentPlaceHolder 的預設內容

圖 07:登入頁面會壓縮 QuickLoginUI ContentPlaceHolder 的預設內容(按兩下以檢視完整大小的影像

使用新頁面中的預設內容

我們想要針對 [登入] 頁面以外的所有頁面,在左欄中顯示 [登入] 控件。 若要達成此目的,除了登入頁面以外的所有內容頁面,都應該省略 ContentPlaceHolder 的內容控制件 QuickLoginUI 。 藉由省略 Content 控件,將會改用 ContentPlaceHolder 的默認內容。

我們現有的內容頁面 - Default.aspxAbout.aspxMultipleContentPlaceHolders.aspx - 不包含 的內容控制件 QuickLoginUI ,因為它們是在將 ContentPlaceHolder 控制件新增至主版頁面之前建立的。 因此,這些現有的頁面不需要更新。 不過,新增至網站的新頁面預設會包含 ContentPlaceHolder 的內容控制件 QuickLoginUI 。 因此,我們必須記得每次新增內容頁面時移除這些內容控件(除非我們想要覆寫 ContentPlaceHolder 的默認內容,就像登入頁面的情況一樣)。

若要移除內容控件,您可以從 [來源] 檢視手動刪除其宣告式標記,或從 [設計] 檢視選擇 [預設為主圖形的內容] 連結。。 任一種方法會從頁面移除 Content 控件,併產生相同的凈效果。

圖 8 顯示 Default.aspx 透過瀏覽器檢視時。 回想一下, Default.aspx 宣告式標記中只指定了兩個 Content 控件,一個用於 head ,另一個用於 MainContent。 因此,會顯示 和 QuickLoginUI ContentPlaceHolders 的預設內容LeftColumnContent

LeftColumnContent 和 QuickLoginUI ContentPlaceHolders 的預設內容隨即顯示

圖 08:顯示 和 QuickLoginUI ContentPlaceHolders 的預設內容 LeftColumnContent按兩下以檢視完整大小的影像

摘要

ASP.NET 主版頁面模型允許主版頁面中任意數目的 ContentPlaceHolders。 此外,ContentPlaceHolders 包含預設內容,在內容頁面中沒有對應的內容控制件時,就會發出此內容。 在本教學課程中,我們已瞭解如何在主版頁面中加入其他 ContentPlaceHolder 控件,以及如何在新的和現有的 ASP.NET 頁面中定義這些新 ContentPlaceHolders 的內容控件。 我們也查看了在 ContentPlaceHolder 中指定預設內容,這在只有少數頁面需要自定義特定區域內其他標準化內容的情況下很有用。

在下一個教學課程中,我們將更詳細地檢查 head ContentPlaceHolder,瞭解如何以宣告方式並以程式設計方式定義逐頁的標題、中繼標記和其他 HTML 標頭。

快樂的程序設計!

關於作者

斯科特·米切爾,多個 ASP/ASP.NET 書籍的作者,4GuysFromRolla.com 的創始人,自1998年以來一直與Microsoft Web 技術合作。 斯科特擔任獨立顧問、教練和作家。 他的最新書是 山姆斯在24小時內 ASP.NET 3.5。 斯科特可以透過 mitchell@4GuysFromRolla.com 他在的部落格聯繫到或通過他的博客 http://ScottOnWriting.NET

特別感謝

本教學課程系列已由許多實用的檢閱者檢閱。 本教學課程的主要檢閱者是 Suchi Banerjee。 有興趣檢閱我即將推出的 MSDN 文章嗎? 如果是,請將一行 mitchell@4GuysFromRolla.com放在 。