简体   繁体   English

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

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

My objective is to render the full web.sitemap as a nested unordered list. 我的目标是将完整的web.sitemap呈现为嵌套的无序列表。 By full, I mean to produce the entire sitemap from root to all descendants. 完整来说,我的意思是要生成从根到所有后代的整个站点地图。 This list must contain the title and url of each node. 该列表必须包含每个节点的标题和URL。

This process is useful when your website is a Windows Authenticated network and you need to create a navigation list with secuirty trimming by Active Directory role. 当您的网站是Windows身份验证网络并且您需要创建一个按Active Directory角色进行安全修剪的导航列表时,此过程很有用。

Context -- This is an asp.net 4.0 webpage using Visual Studio 2010. I use strict = true and explicit = true . 上下文 -这是一个使用Visual Studio 2010的asp.net 4.0网页。我使用strict = trueexplicit = true

Background & What I've done so far 背景和到目前为止我所做的

This page https://msdn.microsoft.com/en-us/library/system.web.sitemap(v=vs.110).aspx shows an example of how to generate a sitemap based on "current node," but I want to generate a full sitemap from the root to all children. 此页面https://msdn.microsoft.com/zh-cn/library/system.web.sitemap(v=vs.110).aspx显示了如何基于“当前节点”生成站点地图的示例,但是我想要生成一个从根到所有子项的完整站点地图。

The URL gave me the inspiration to set up a recursive function, but my problem is while I can get the node titles I am unable to get the node URL to accompany it. URL给了我启发,我建立了一个递归函数,但是我的问题是当我可以获取节点标题时,我无法获得它所伴随的节点URL

Update (5/7/2015): I learned that I was missing a critical piece of code necessary to get the URL of the "current" node. 更新(2015年5月7日):我了解到我缺少获取“当前”节点URL所需的关键代码。 The ordered list emphasizes the new additions, and I'm posting my refreshed code. 有序列表强调新添加的内容,我将发布刷新的代码。

I have discovered that while I can get two levels deep from the root node, I am not going any further, which leads me to believe that the recursion script is not defined correctly. 我发现虽然可以从根节点深入了解两个级别,但我没有做进一步的工作,这使我相信递归脚本未正确定义。

*This goes in the LoadMe sub * *这在LoadMe子文件夹中*

  1. Dim node As SiteMapNode -- this variable is defined before the while loop and represents the "current" node in the while loop. Dim node As SiteMapNode此变量在while循环之前定义,表示while循环中的“当前”节点。
  2. node = CType(rootNodesChildrenEnumerator.Current, SiteMapNode) -- the node value is updated each pass through the while loop node = CType(rootNodesChildrenEnumerator.Current, SiteMapNode) -节点值通过while循环每次更新
  3. node.Url -- this is how to read the URL of the "current" node node.Url -这是如何读取“当前”节点的URL

*This goes in the List_Childnodes function * *这在List_Childnodes函数中使用*

  1. Dim node As SiteMapNode
  2. node = CType(childNodesEnumerator.Current, SiteMapNode)
  3. sb.Append(childNodesEnumerator.Current.ToString())

Here is the full (updated) code. 这是完整的(更新的)代码。

Thank you for any ideas you can provide in improving the recursion and ideas to make the code syntax better. 感谢您提供任何改进递归的想法,以及使代码语法更好的想法。

<%@ 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>

It turned out that all I needed was to write one line differently. 原来,我所需要的只是写不同的一行。

List_Childnodes(node) should have been sb.Append(List_Childnodes(node)) List_Childnodes(node)应该是sb.Append(List_Childnodes(node))

I verified that security trimming of roles (as defined in web.sitemap) works very well. 我验证了角色的安全修整(在web.sitemap中定义)可以很好地工作。

Edit: I also realized that I needed to call the List_ChildNodes(node) function before I closed the </li> tag. 编辑:我还意识到我需要关闭</li>标记之前调用List_ChildNodes(node)函数。 Now the nested UL is properly formed. 现在,嵌套的UL已正确形成。

Second edit: I also wrapped Page.ResolveClientUrl() around node.url to make absolutely sure the links will work properly when viewed from both localhost and the server. 第二个编辑:我还裹着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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM