ASP.NET 2.0 引入 <head runat="server"> 使頁面標題成為可程式控制的伺服器屬性。結合 SiteMapProvider,可自動根據目前節點路徑產生如「首頁 > 產品 > 筆電」的階層式標題,提升 SEO 與使用者導向體驗。
<head runat="server">
<title>預設標題</title>
</head>
程式碼後置即可存取 Page.Title 或 Page.Header.Title:
protected void Page_Load(object sender, EventArgs e)
{
Page.Title = $"目前時間:{DateTime.Now:yyyy/MM/dd HH:mm}";
// 或
Page.Header.Title = "動態標題";
}
Const DEFAULT_UNNAMED_PAGE_TITLE As String = "Untitled Page"
Const DEFAULT_PAGE_TITLE As String = "歡迎光臨本網站!!"
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
' 僅在標題為預設值時自動產生
If String.IsNullOrEmpty(Page.Title) OrElse Page.Title = DEFAULT_UNNAMED_PAGE_TITLE Then
If SiteMap.CurrentNode Is Nothing Then
Page.Title = DEFAULT_PAGE_TITLE
Else
Page.Title = GetPageTitleBasedOnSiteNavigation()
' 遞迴版本:Page.Title = GetPageTitleBasedOnSiteNavigationUsingRecursion(SiteMap.CurrentNode)
End If
End If
End Sub
Private Function GetPageTitleBasedOnSiteNavigation() As String
If SiteMap.CurrentNode Is Nothing Then
Throw New ArgumentException("currentNode cannot be Nothing")
End If
Dim output As String = String.Empty
Dim currentNode As SiteMapNode = SiteMap.CurrentNode
' 從目前節點向上走到根節點,建立「子 :: 父 :: 根」格式
While currentNode IsNot Nothing
If output.Length > 0 Then
output = currentNode.Title & " :: " & output
Else
output = currentNode.Title
End If
currentNode = currentNode.ParentNode
End While
Return output
End Function
' 遞迴替代版本
Private Function GetPageTitleBasedOnSiteNavigationUsingRecursion(ByVal node As SiteMapNode) As String
If node Is Nothing Then Return String.Empty
Dim parentTitle = GetPageTitleBasedOnSiteNavigationUsingRecursion(node.ParentNode)
Return If(String.IsNullOrEmpty(parentTitle), node.Title, parentTitle & " :: " & node.Title)
End Function
const string DefaultUnnamedTitle = "Untitled Page";
const string DefaultTitle = "歡迎光臨本網站!!";
protected void Page_Load(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(Page.Title) || Page.Title == DefaultUnnamedTitle)
{
Page.Title = SiteMap.CurrentNode == null
? DefaultTitle
: BuildTitleFromSiteMap(SiteMap.CurrentNode);
}
}
private string BuildTitleFromSiteMap(SiteMapNode node)
{
var titles = new List();
while (node != null)
{
titles.Add(node.Title);
node = node.ParentNode;
}
titles.Reverse(); // 根 -> ... -> 目前
return string.Join(" :: ", titles);
}
<?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="https://schemas.microsoft.com/AspNet/SiteMap-File-1.0">
<siteMapNode url="~/Default.aspx" title="首頁" description="網站首頁">
<siteMapNode url="~/Products.aspx" title="產品介紹" description="產品列表">
<siteMapNode url="~/Products/Laptops.aspx" title="筆記型電腦" />
<siteMapNode url="~/Products/Phones.aspx" title="智慧型手機" />
</siteMapNode>
<siteMapNode url="~/About.aspx" title="關於我們" />
<siteMapNode url="~/Contact.aspx" title="聯絡我們" />
</siteMapNode>
</siteMap>
<system.web>
<siteMap defaultProvider="XmlSiteMapProvider" enabled="true">
<providers>
<add name="XmlSiteMapProvider"
type="System.Web.XmlSiteMapProvider"
siteMapFile="Web.sitemap"
securityTrimmingEnabled="true" />
</providers>
</siteMap>
</system.web>
<%@ Master Language="C#" AutoEventWireup="true" CodeBehind="Site.master.cs" Inherits="MySite.SiteMaster" %>
<!DOCTYPE html>
<html>
<head runat="server" id="Head1">
<title><asp:ContentPlaceHolder ID="TitleContent" runat="server" /></title>
<asp:ContentPlaceHolder ID="HeadContent" runat="server" />
</head>
<body>
<form runat="server">
<asp:SiteMapPath ID="SiteMapPath1" runat="server" />
<asp:ContentPlaceHolder ID="MainContent" runat="server" />
</form>
</body>
</html>
// Site.master.cs
protected void Page_Load(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(Page.Title) || Page.Title == "Untitled Page")
{
Page.Title = BuildTitleFromSiteMap(SiteMap.CurrentNode) ?? "歡迎光臨";
}
}
目前頁面 | 父分類 | 網站名稱(如 筆記型電腦 :: 產品介紹 :: 我的購物網)。<meta name="description"> 動態產生描述。securityTrimmingEnabled="true",未授權頁面不出現在導航與標題產生邏輯中。動態頁面標題是 SEO 與 UX 的基礎建設。ASP.NET 2.0 的 Head 控制項與 SiteMap 機制,讓開發者以極少程式碼實現全站統一、階層感清晰的標題策略。現代專案建議改用 ASP.NET Core 的 ViewData["Title"] + Layout Page 或 Tag Helper 實現同樣目標。