如何在脚本中将整个站点地图呈现为列表,同时读取标题和 url?

How can I render an entire sitemap in script as a list, reading both title and url?

我的 objective 是将完整的 web.sitemap 呈现为嵌套的无序列表。完整的意思是生成从根到所有后代的整个站点地图。此列表必须包含每个节点的标题和 url。

当您的网站是 Windows 经过身份验证的网络并且您需要通过 Active Directory 角色创建具有安全修整的导航列表时,此过程很有用。

Context -- 这是一个使用 Visual Studio 2010 的 asp.net 4.0 网页。我使用 strict = trueexplicit = true

背景和我目前所做的事情

此页面 https://msdn.microsoft.com/en-us/library/system.web.sitemap(v=vs.110).aspx 显示了如何根据 "current node," 生成站点地图的示例,但我想生成从根目录到所有 children 的完整站点地图。

URL给了我建立递归函数的灵感,但我的问题是虽然我可以获取节点titles我无法获取节点URL陪着吧

更新(2015 年 5 月 7 日): 我了解到我缺少获取 [=80= 的 URL 所必需的关键代码段] 节点。有序列表强调了新添加的内容,我正在发布我刷新的代码。

我发现虽然我可以从根节点深入两层,但我不会再进一步​​,这让我相信递归脚本没有正确定义。

*这在 LoadMe sub *

  1. Dim node As SiteMapNode -- 这个变量定义在while循环之前,表示while循环中的"current"节点。
  2. node = CType(rootNodesChildrenEnumerator.Current, SiteMapNode) -- 每次通过 while 循环更新节点值
  3. node.Url -- 这是如何读取 "current" 节点的 URL

*这进入List_Childnodes函数*

  1. Dim node As SiteMapNode
  2. node = CType(childNodesEnumerator.Current, SiteMapNode)
  3. 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>

原来我需要的只是写一行不同的东西。

List_Childnodes(node) 应该是 sb.Append(List_Childnodes(node))

我验证了角色的安全修整(如 web.sitemap 中所定义)工作得很好。

编辑: 我也意识到我需要调用 List_ChildNodes(node) 函数 before 我关闭了 </li> 标签。现在嵌套的 UL 已正确形成。

第二次编辑: 我还在 node.url 周围包裹了 Page.ResolveClientUrl() 以绝对确保从本地主机和服务器查看时链接都能正常工作。

         <%@ Page Title="" Language="VB" MasterPageFile="~/MasterPage.master" %>

    <script runat="server">
     Public strSitemap As String = String.Empty
     Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
         Dim sb As New StringBuilder
         ' Examine the RootNode, and navigate the SiteMap relative to it.

         ' 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)
                 If node.Url IsNot Nothing Then
                     sb.Append("<li><a href=""" & Page.ResolveClientUrl(node.Url) & """>" & rootNodesChildrenEnumerator.Current.ToString() & "</a>" & vbCrLf)
                 Else
                     sb.Append("<li>" & rootNodesChildrenEnumerator.Current.ToString() & vbCrLf)
                 End If

                 sb.Append(vbTab & List_Childnodes(CType(rootNodesChildrenEnumerator.Current, SiteMapNode)))
                 sb.Append("</li>")
             End While
         End If

         strSitemap = 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(vbTab & "<ul>")
             While (childNodesEnumerator.MoveNext())
                 ' Prints the Title of each node.
                 Dim node As SiteMapNode = CType(childNodesEnumerator.Current, SiteMapNode)
                 sb.Append(vbTab & "<li>")
                 sb.Append("<a href=""" & Page.ResolveClientUrl(node.Url) & """>")
                 sb.Append(childNodesEnumerator.Current.ToString())
                 sb.Append("</a>")
                 ' this is how the recursion captures all child nodes                
                 sb.Append(List_Childnodes(node))
                 sb.Append("</li>" & vbCrLf)

             End While
             sb.Append("</ul>" & vbCrLf)
         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>
        <ul>
            <li>
                <asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl="~/index.aspx">Homepage</asp:HyperLink></li>
            <%= strSitemap%>
        </ul>
    </asp:Content>