Building a TreeView of your Directory Structure using XML, WebServices, and Delegates

TreeViews provide a great way for displaying a hierarchal view of a website, directory, company, and the list goes on.  You can build a TreeView by binding it to a datasource, or by manually adding the nodes.  Today we are going to look at building a TreeView of a directory structure for a website.  To do this we are going to create a WebService that utilizes Delegates to traverse the directory and return an XMLDocument to our web page which will then be bound to our TreeView.

First off lets take a quick look at why we are using a delegate when traversing the directory.  We could have just created a method that returns all the folders using Directory.GetDirectories and then process them all in a loop.  However; if the path being traversed contains thousands of items, then the application will most likely freeze and ignore any input from the user.  What delegates does is provides for us a way to traverse the directory and build our xml through a callback function thus giving control back to the user while this is taking place. 

WebService : DirectoryInfoView

<WebMethod()> _
    Public Function GetDirectoryInfo(ByVal path As String, ByVal sessionguid As String) As XmlDocument
        Dim tmpDocument As New XmlDocument
        If Not sessionguid = Session("wscall").ToString Then
            Throw New Exception("Security Exception:  You are not allowed to access this service")
        End If
        xmlWriter.Formatting = Formatting.None
        xmlWriter.WriteProcessingInstruction("xml", "version='1.0' encoding='UTF-16'")
        xmlWriter.WriteStartElement("SiteMapNode")
        xmlWriter.WriteAttributeString("url", path)
        xmlWriter.WriteAttributeString("title", (New DirectoryInfo(path).Name))
        TraverseDirectoryTree(path, AddressOf AddDirName)
        xmlWriter.Close()
        tmpDocument.LoadXml(UTF8ByteArrayToString(memStream.ToArray()))
        Return tmpDocument
    End Function

    Private Delegate Sub TraverseDirectoryTreeCallBack(ByVal dirName As String)

    Private Sub TraverseDirectoryTree(ByVal path As String, ByVal cbk As TraverseDirectoryTreeCallBack)
        For Each fileName As String In Directory.GetFiles(path)
            cbk.Invoke(fileName)
            xmlWriter.WriteEndElement()
        Next
        For Each dirName As String In Directory.GetDirectories(path)
            cbk.Invoke(dirName)
            TraverseDirectoryTree(dirName, cbk)
        Next
        xmlWriter.WriteEndElement()
    End Sub

    Private Sub AddDirName(ByVal path As String)
        xmlWriter.WriteStartElement("SiteMapNode")
        xmlWriter.WriteAttributeString("url", path)
        xmlWriter.WriteAttributeString("title", (New DirectoryInfo(path).Name))
    End Sub

    Private Function UTF8ByteArrayToString(ByVal characters As Byte()) As String

        Dim encoding As New UTF8Encoding()
        Dim constructedString As String = encoding.GetString(characters)
        Return (constructedString)
    End Function

Default.aspx

Here we call our webservice and bind it to an XMLDataSource.  You will also notice in our TreeView how we are binding the TreeNode to the XML.

Private Sub GetDirectoryInfo(ByVal path As String)
    Dim ws As New DirectoryInfoView
    Dim treeNode As New TreeNodeBinding
    Me.XmlDataSource1.Data = ws.GetDirectoryInfo(path, Session("wscall").ToString).OuterXml
    Me.XmlDataSource1.DataBind()
End Sub

 

<asp:TreeView ID="TreeView1" runat="server" DataSourceID="XmlDataSource1">
    <DataBindings>
        <asp:TreeNodeBinding DataMember="SiteMapNode" ValueField="url" TextField="title" />
    </DataBindings>              
</asp:TreeView>
<asp:XmlDataSource ID="XmlDataSource1" runat="server"></asp:XmlDataSource>

 

Giving us a final result of.

image

Project File DirectoryTreeView

xml webservices .net vb.net

No Comments