1

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

当您的网站是 Windows Authenticated 网络并且您需要通过 Active Directory 角色创建具有安全修剪的导航列表时,此过程非常有用。

上下文——这是一个使用 Visual Studio 2010 的 asp.net 4.0 网页。我使用strict = trueexplicit = true.

背景和我到目前为止所做的事情

此页面https://msdn.microsoft.com/en-us/library/system.web.sitemap(v=vs.110).aspx显示了如何基于“当前节点”生成站点地图的示例,但我想要生成从根到所有孩子的完整站点地图。

URL 给了我设置递归函数的灵感,但我的问题是,虽然我可以获得节点标题,但我无法获得节点URL来伴随它。

更新(2015 年 5 月 7 日):我了解到我缺少获取“当前”节点 URL 所需的关键代码。有序列表强调了新增内容,我发布了我更新的代码。

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

*这在 LoadMe 子中 *

  1. Dim node As SiteMapNode -- 这个变量在while循环之前定义,代表while循环中的“当前”节点。
  2. node = CType(rootNodesChildrenEnumerator.Current, SiteMapNode)-- 每次通过while循环更新节点值
  3. node.Url-- 这是如何读取“当前”节点的 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>

4

1 回答 1

1

事实证明,我所需要的只是用不同的方式写一行。

List_Childnodes(node)本来应该sb.Append(List_Childnodes(node))

我验证了角色的安全修整(如 web.sitemap 中定义的)效果很好。

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

第二次编辑:我还Page.ResolveClientUrl()环绕node.url以确保从本地主机和服务器查看时链接将正常工作。

         <%@ 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>
于 2015-05-08T15:06:25.057 回答