1

私の目的は、完全な 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 サブに入ります *

  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

必要なのは、1 行を別の方法で書くことだけであることがわかりました。

List_Childnodes(node)になるはずだったsb.Append(List_Childnodes(node))

ロールのセキュリティ トリミング (web.sitemap で定義) が非常にうまく機能することを確認しました。

編集:タグを閉じるList_ChildNodes(node)に関数を呼び出す必要があることにも気付きました。これで、ネストされた UL が適切に形成されました。</li>

2番目の編集:ローカルホストとサーバーの両方から表示したときにリンクが正しく機能することを完全に確認するために、ラップ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 に答える