HOW TO:在記憶體中以程式設計方式修改網站導覽節點
更新:2007 年 11 月
網站經常會使用包含附加為查詢字串資訊的動態 URL。例如,新聞群組或論壇站台可能會包含指向論壇或群組的靜態 URL,以及每次張貼的動態 URL。張貼的 URL 可能會使用下列格式:https://www.microsoft.com/newsgroups/ShowPost.aspx?ForumID=2&PostID=53
因為無法以程式的方式將節點加入網站導覽,所以更新網站導覽以列出每次張貼的 URL 並不是一個有效率的方法。但是,當使用者檢視張貼時,您可以使用 SiteMapPath 控制項顯示回到根節點的巡覽路徑,並且動態地將查詢字串附加到路徑中的每個連結,以識別張貼、論壇或群組。例如,連至前一張貼的巡覽路徑可能如下所示:
首頁 > 論壇清單 > 張貼清單
「張貼」網站導覽節點的靜態 Url 屬性,可以設定為 https://www.microsoft.com/newsgroups/ShowPost.aspx。但是在記憶體中,您可以修改 SiteMapPath 控制項中的 URL,以識別論壇和特定張貼。
您可以使用下列程序和範例所示的 SiteMapResolve 事件,變更記憶體中的網站導覽節點。
若要使用程式方式變更網站導覽節點
在 Web Form 網頁的程式碼中,建立處理 SiteMapResolve 事件的方法。例如,下列宣告會建立名為 ExpandForumPaths 的方法。
private SiteMapNode ExpandForumPaths(Object sender, SiteMapResolveEventArgs e)
Private Function ExpandForumPaths(ByVal sender As Object, ByVal e As SiteMapResolveEventArgs) As SiteMapNode
在事件處理常式中,取得目前節點的參考並予以複製。例如,如果節點是新聞群組張貼,您的程式碼可能如下所示。
SiteMapNode currentNode = SiteMap.CurrentNode.Clone(true); SiteMapNode tempNode = currentNode;
Dim currentNode As SiteMapNode = SiteMap.CurrentNode.Clone(True) Dim tempNode As SiteMapNode = currentNode
tempNode 變數會傳回在記憶體中周遊的網站導覽節點,修改每個 Url 屬性或其他屬性。因為事件處理常式的預期回傳值是目前節點的參考,因此 nodeCopy 中的參考是個別維護的,但是,tempNode 變數會用來遞迴地上移巡覽結構。
注意事項: 因為複製的節點有別於靜態站台巡覽結構,所以 Url 屬性的變更不會保存在記憶體,也不會儲存在磁碟中。
變更目前節點和父節點的 Url 屬性,以包含列出張貼、論壇和群組識別項的查詢字串資訊。
例如,下列程式碼範例假設存在三種取得識別項的方法。
int forumGroupID = GetMostRecentForumGroupID(); int forumID = GetMostRecentForumID(forumGroupID); int postID = GetMostRecentPostID(forumID); if (0 != postID) { tempNode.Url = tempNode.Url + "?PostID=" + postID.ToString(); } if ((null != (tempNode = tempNode.ParentNode)) && (0 != forumID)) { tempNode.Url = tempNode.Url + "?ForumID=" + forumID.ToString(); } if ((null != (tempNode = tempNode.ParentNode)) && (0 != forumGroupID)) { tempNode.Url = tempNode.Url + "?ForumGroupID=" + forumGroupID.ToString(); }
Dim forumGroupID As Integer = GetMostRecentForumGroupID() Dim forumID As Integer = GetMostRecentForumID(forumGroupID) Dim postID As Integer = GetMostRecentPostID(forumID) If Not (0 = postID) Then tempNode.Url = tempNode.Url & "?PostID=" & postID.ToString() End If tempNode = tempNode.ParentNode If Not (0 = forumID) And Not (Nothing = tempNode) Then tempNode.Url = tempNode.Url & "?ForumID=" & forumID.ToString() End If tempNode = tempNode.ParentNode If Not (0 = ForumGroupID) And Not (Nothing = tempNode) Then tempNode.Url = tempNode.Url & "?ForumGroupID=" & forumGroupID.ToString() End If
注意事項: if 陳述式用來確定只有在可以使用群組、論壇和張貼識別項的情況下,將查詢字串僅加入至現有的網站導覽節點。
使用下列程式碼行傳回複製的節點。
return currentNode;
Return currentNode
在 Page_Load 方法中註冊事件處理常式。例如,程式碼可能如下列範例所示。
SiteMap.SiteMapResolve += new SiteMapResolveEventHandler(this.ExpandForumPaths);
AddHandler SiteMap.SiteMapResolve, AddressOf Me.ExpandForumPaths
注意事項: 當網站導覽提供者存取 CurrentNode 屬性時,會引發 SiteMapResolve 事件,例如當 SiteMapPath 控制項呈現巡覽結構時。
將 SiteMapPath 控制項加入 Web Form 網頁,以便檢視巡覽結構。SiteMapPath 控制項可能如下所示。
<asp:SiteMapPath id="SiteMapPath1" RenderCurrentNodeAsLink="true" />
請確定網站導覽檔案中有 Web Form 網頁的節點。例如,如果 Web Form 網頁稱為 ShowPost.aspx,Web.sitemap 檔可能如下所示。
<?xml version="1.0" encoding="utf-8" ?> <siteMap> <siteMapNode title="Forum Group" description="Forum Group List" url="default.aspx"> <siteMapNode title="Forum" description="Forum List" url="ShowForum.aspx"> <siteMapNode title="Post" description="Post List" url="ShowPost.aspx" /> </siteMapNode> </siteMapNode> </siteMap>
範例
下列程式碼範例,示範如何處理 ASP.NET Web 網頁上的 SiteMapResolve 事件,以修改 SiteMapPath 控制項所顯示的目標 URL。在這個範例中,目前頁面是線上電子佈告欄或論壇的張貼頁面。若要呈現更有意義的站台巡覽,請將與內容相關的查詢字串附加至 SiteMapPath 控制項所顯示節點的 URL。請使用下列程式碼呈現控制項。
<asp:SiteMapPath
id="SiteMapPath1"
RenderCurrentNodeAsLink="true" />
<asp:SiteMapPath
id="SiteMapPath1"
RenderCurrentNodeAsLink="true" />
當執行範例時,請將游標停留在 SiteMapPath 控制項中的連結,觀察 URL 的變化。
這個範例不會將 SiteMapNode 項目加入至 Web.sitemap 檔,您只能手動編輯 Web.sitemap 檔。
注意事項: |
---|
從 SiteMapResolveEventHandler 存取 CurrentNode 屬性是安全的。在這個案例中,ASP.NET 站台巡覽基礎結構會避免發生無限遞迴。 |
這個範例假設已經存在有效的網站導覽檔案,並且目前的頁面在網站導覽結構中至少三個節點深的位置。如需建立網站導覽的詳細資訊,請參閱 ASP.NET 網站導覽。
Private Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)
' The ExpandForumPaths method is called to handle
' the SiteMapResolve event.
AddHandler SiteMap.SiteMapResolve, AddressOf Me.ExpandForumPaths
End Sub
Private Function ExpandForumPaths(ByVal sender As Object, ByVal e As SiteMapResolveEventArgs) As SiteMapNode
' The current node represents a Post page in a bulletin board forum.
' Clone the current node and all of its relevant parents. This
' returns a site map node that a developer can then
' walk, modifying each node.Url property in turn.
' Since the cloned nodes are separate from the underlying
' site navigation structure, the fixups that are made do not
' effect the overall site navigation structure.
Dim currentNode As SiteMapNode = SiteMap.CurrentNode.Clone(True)
Dim tempNode As SiteMapNode = currentNode
' Obtain the recent IDs.
Dim forumGroupID As Integer = GetMostRecentForumGroupID()
Dim forumID As Integer = GetMostRecentForumID(forumGroupID)
Dim postID As Integer = GetMostRecentPostID(forumID)
' The current node, and its parents, can be modified to include
' dynamic querystring information relevant to the currently
' executing request.
If Not (0 = postID) Then
tempNode.Url = tempNode.Url & "?PostID=" & postID.ToString()
End If
tempNode = tempNode.ParentNode
If Not (0 = forumID) And Not (tempNode Is Nothing) Then
tempNode.Url = tempNode.Url & "?ForumID=" & forumID.ToString()
End If
tempNode = tempNode.ParentNode
If Not (0 = ForumGroupID) And Not (tempNode Is Nothing) Then
tempNode.Url = tempNode.Url & "?ForumGroupID=" & forumGroupID.ToString()
End If
Return currentNode
End Function
...
' These methods are just placeholders for the example.
' One option is to use the HttpContext or e.Content object
' to obtain the ID.
Private Function GetMostRecentForumGroupID() As Integer
Return 24
End Function
Private Function GetMostRecentForumID(ByVal forumGroupId As Integer) As Integer
Return 128
End Function
Private Function GetMostRecentPostID(ByVal forumId As Integer) As Integer
Return 317424
End Function
private void Page_Load(object sender, EventArgs e)
{
// The ExpandForumPaths method is called to handle
// the SiteMapResolve event.
SiteMap.SiteMapResolve +=
new SiteMapResolveEventHandler(this.ExpandForumPaths);
}
private SiteMapNode ExpandForumPaths(Object sender, SiteMapResolveEventArgs e)
{
// The current node represents a Post page in a bulletin board forum.
// Clone the current node and all of its relevant parents. This
// returns a site map node that a developer can then
// walk, modifying each node.Url property in turn.
// Since the cloned nodes are separate from the underlying
// site navigation structure, the fixups that are made do not
// effect the overall site navigation structure.
SiteMapNode currentNode = SiteMap.CurrentNode.Clone(true);
SiteMapNode tempNode = currentNode;
// Obtain the recent IDs.
int forumGroupID = GetMostRecentForumGroupID();
int forumID = GetMostRecentForumID(forumGroupID);
int postID = GetMostRecentPostID(forumID);
// The current node, and its parents, can be modified to include
// dynamic querystring information relevant to the currently
// executing request.
if (0 != postID)
{
tempNode.Url = tempNode.Url + "?PostID=" + postID.ToString();
}
if ((null != (tempNode = tempNode.ParentNode)) &&
(0 != forumID))
{
tempNode.Url = tempNode.Url + "?ForumID=" + forumID.ToString();
}
if ((null != (tempNode = tempNode.ParentNode)) &&
(0 != forumGroupID))
{
tempNode.Url = tempNode.Url + "?ForumGroupID=" + forumGroupID.ToString();
}
return currentNode;
}
...
// These methods are just placeholders for the example.
// One option is to use the HttpContext or e.Content object
// to obtain the ID.
private int GetMostRecentForumGroupID()
{
return 24;
}
private int GetMostRecentForumID(int forumGroupId)
{
return 128;
}
private int GetMostRecentPostID(int forumId)
{
return 317424;
}
安全性
使用查詢字串和表單資料要注意的重點是驗證傳遞的資料。ASP.NET 提供一組驗證控制項,可提供易用但強大的方式來檢查錯誤,並視需要對使用者顯示訊息。前面的範例中並未使用驗證控制項,以便將重點放在變更網站導覽節點的工作上。如需「如何在程式碼中加入驗證」的詳細資訊,請參閱驗證 ASP.NET 控制項。