私の目的は、完全な web.sitemap をネストされた順序なしリストとしてレンダリングすることです。フルとは、ルートからすべての子孫までのサイトマップ全体を作成することを意味します。このリストには、各ノードのタイトルと URL が含まれている必要があります。
このプロセスは、Web サイトが Windows 認証ネットワークであり、Active Directory ロールによるセキュリティ トリミングを使用してナビゲーション リストを作成する必要がある場合に役立ちます。
コンテキスト- これは、Visual Studio 2010 を使用した asp.net 4.0 Web ページstrict = true
ですexplicit = true
。
背景と今までやってきたこと
このページhttps://msdn.microsoft.com/en-us/library/system.web.sitemap(v=vs.110).aspxは、「現在のノード」に基づいてサイトマップを生成する方法の例を示していますが、ルートからすべての子への完全なサイトマップを生成したい。
URL は、再帰関数をセットアップするためのインスピレーションを与えてくれましたが、私の問題は、ノードタイトルを取得できる一方で、それに付随するノードURLを取得できないことです。
更新 (2015 年 5 月 7 日):「現在の」ノードの URL を取得するために必要な重要なコードが欠落していることを知りました。順序付けされたリストは新しい追加を強調しており、更新されたコードを投稿しています。
ルート ノードから 2 レベルの深さまで取得できますが、それ以上先に進めないことがわかりました。これにより、再帰スクリプトが正しく定義されていないと思われます。
*これは LoadMe サブに入ります *
Dim node As SiteMapNode
-- この変数は while ループの前に定義され、while ループ内の「現在の」ノードを表します。node = CType(rootNodesChildrenEnumerator.Current, SiteMapNode)
-- ノード値は while ループを通過するたびに更新されますnode.Url
-- これは、「現在の」ノードの URL を読み取る方法です。
*これは List_Childnodes 関数に含まれます *
Dim node As SiteMapNode
node = CType(childNodesEnumerator.Current, SiteMapNode)
sb.Append(childNodesEnumerator.Current.ToString())
これが完全な(更新された)コードです。
再帰を改善するために提供できるアイデアと、コード構文を改善するためのアイデアをありがとう。
<%@ Page Title="Sitemap Test" Language="VB" MasterPageFile="~/MasterPage.master" Strict="true" Explicit="true" %>
<script runat="server">
Private Sub LoadMe(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim sb As New StringBuilder
' Examine the RootNode, and navigate the SiteMap relative to it.
sb.Append("<ul>")
sb.Append("<li><a href=""" & Page.ResolveClientUrl(SiteMap.RootNode.Url) & """>" & SiteMap.RootNode.Title & "</a></li>")
' What nodes are children of the RootNode?
If (SiteMap.RootNode.HasChildNodes) Then
Dim rootNodesChildrenEnumerator As IEnumerator = SiteMap.RootNode.ChildNodes.GetEnumerator()
Dim node As SiteMapNode
While (rootNodesChildrenEnumerator.MoveNext())
node = CType(rootNodesChildrenEnumerator.Current, SiteMapNode)
sb.Append("<li><a href=""" & node.Url & """>" & rootNodesChildrenEnumerator.Current.ToString() & "</a></li>")
sb.Append(List_Childnodes(CType(rootNodesChildrenEnumerator.Current, SiteMapNode)))
End While
End If
sb.Append("</ul>")
lblSitemap.Text = sb.ToString
End Sub
Function List_Childnodes(Current_Node As SiteMapNode) As String
Dim sb As New StringBuilder
' What nodes are children of the function parameter?
If (Current_Node.HasChildNodes) Then
Dim childNodesEnumerator As IEnumerator = Current_Node.ChildNodes.GetEnumerator()
sb.Append("<ul>")
Dim node As SiteMapNode
While (childNodesEnumerator.MoveNext())
' Prints the Title of each node.
node = CType(childNodesEnumerator.Current, SiteMapNode)
sb.Append("<li>")
sb.Append("<a href=""" & node.Url & """>")
sb.Append(childNodesEnumerator.Current.ToString())
sb.Append("</a>")
sb.Append("</li>")
' Because I didn't get all children, I tried calling the same function here
' to see if I could get all child descendents.
' this didn't work
List_Childnodes(node)
End While
sb.Append("</ul>")
End If
Return sb.ToString
End Function
</script>
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="Server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
<h1>Sitemap Test</h1>
<p>The <var>LoadMe</var> sub runs on Me.Load and recursively calls all children. The root node is manually moved into the first level for user convenience.</p>
<h2>Sitemap tree</h2>
<asp:Label ID="lblSitemap" runat="server" Text="Label"></asp:Label>