ASP.NET TreeView control on MasterPage not always populating

I'm working on my first ASP.Net project and I seem to have thrown into the deep end right away. All of my site's files are stored in the database, so I use the VirtualPathProvider to access them. This part works well, but then I need a sitemap that will collect all the files dynamically as the user will add / remove files as they come in. For this, I created a class that inherits from StaticSiteMapProvider, created a SiteMapDataSource on my main page and a TreeView to use it. For the most part, it works. When you load the page, you see a TreeView and it contains all the nodes it targets. However, at times the TreeView is completely empty - no nodes at all. I even copied the TreeView to the content page. TreeView content page always works,even if MasterPage doesn't work. (Also I didn't know that a control on the content page could use the data source on the master page until I forgot to copy the data source!)

Trying to debug this, I put a throw exception in my BuildSiteMap () function in the SiteMapProvider just to prove to myself that the code actually works. I found that the exception succeeded every time. However, the stack trace was not the same every time.

Most of the time this is what I got:

[Exception: Test]
    ADEM.clsSiteMap.BuildSiteMap () in c: \ inetpub \ wwwroot \ App_Code \ clsSiteMap.vb: 49
    System.Web.StaticSiteMapProvider.GetChildNodes (SiteMapNode node) +54
    System.Web.SiteMapNode.get_ChildNodes () +27
    System.Web.UI.WebControls.SiteMapDataSource.GetNodes (SiteMapNode node) +52
    System.Web.UI.WebControls.SiteMapDataSource.GetNodes () +329
    System.Web.UI.WebControls.SiteMapDataSource.GetTreeView (String viewPath) +35
    System.Web.UI.WebControls.SiteMapDataSource.GetHierarchialView (String viewPath) +32
    System.Web.UI.HierarchialDataSourceControl.System.Web.UI.IHierarchialDataSource.GetHierarchialView (String viewPath) +10
    System.Web.UI.WebControls.HierarchialDataBoundControl.GetData (String viewPath) +25
    System.Web.UI.WebControls.TreeView.DataBindNode (TreeNode node) +73
    System.Web.UI.WebControls.TreeView.PerformDataBinding () +120
    System.Web.UI.WebControls.HierarchicalDataBoundControl.PerformSelect () +85
    System.Web.UI.WebControls.BaseDataBoundControl.DataBind () +73
    System.Web.UI.WebControls.TreeView.DataBind () +4
    System.Web.UI.WebControls.BaseDataBoundControl.EnsureDataBound () +82
    System.Web.UI.WebControls.BaseDataBoundControl.OnPreRender (EventArgs e) +22
    System.Web.UI.WebControls.TreeView.OnPreRender (EventArgs e) +36
    System.Web.UI.Control.PreRenderRecursiveInternal () +80
    System.Web.UI.Control.PreRenderRecursiveInternal () +171
    System.Web.UI.Control.PreRenderRecursiveInternal () +171
    System.Web.UI.Control.PreRenderRecursiveInternal () +171
    System.Web.UI.Page.ProcessRequestMain (Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +842

However, in about the same way as the TreeView would be empty, I got this:

    [Exception: Test]
    ADEM.clsSiteMap.BuildSiteMap () in c: \ inetpub \ wwwroot \ App_Code \ clsSiteMap.vb: 49
    System.Web.StaticSiteMapProvider.FindSiteMapNode (String rawUrl) +133
    System.Web.SiteMapProvider.FindSiteMapNode (HttpContext context) +54
    System.Web.SiteMapProvider.get_CurrentNode () +35
    System.Web.UI.WebControls.TreeView.DataBindNode (TreeNode node) +219
    System.Web.UI.WebControls.TreeView.PerformDataBinding () +120
    System.Web.UI.WebControls.HierarchicalDataBoundControl.PerformSelect () +85
    System.Web.UI.WebControls.BaseDataBoundControl.DataBind () +73
    System.Web.UI.WebControls.TreeView.DataBind () +4
    System.Web.UI.WebControls.BaseDataBoundControl.EnsureDataBound () +82
    System.Web.UI.WebControls.BaseDataBoundControl.OnPreRender (EventArgs e) +22
    System.Web.UI.WebControls.TreeView.OnPreRender (EventArgs e) +36
    System.Web.UI.Control.PreRenderRecursiveInternal () +80
    System.Web.UI.Control.PreRenderRecursiveInternal () +171
    System.Web.UI.Control.PreRenderRecursiveInternal () +171
    System.Web.UI.Control.PreRenderRecursiveInternal () +171
    System.Web.UI.Page.ProcessRequestMain (Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +842

I guess a useful bit of code would be the BuildSiteMap function:



Public Overrides Function BuildSiteMap() As System.Web.SiteMapNode
    Dim node As SiteMapNode = Nothing

    SyncLock Me
        node = TryCast(HttpRuntime.Cache("SiteMap"), SiteMapNode)
        If node Is Nothing Then
            MyBase.Clear()
            Throw New Exception("Test")
            node = New SiteMapNode(Me, "FO1", "default.cnt", "Home")

            AddNode(node)
            siteRoot = node
            AddFolders(node)
            AddFiles(node)
            HttpRuntime.Cache.Insert("SiteMap", node, New SiteMapCacheDependency())
        End If

        Return node
    End SyncLock
End Function

      

code>

AddFolders () and AddFiles () just do more of the same, so for the sake of brevity I'll leave them out unless someone thinks they're important.

I tried to post the code for the tree structure here, but the site doesn't seem to like it very much. I will say that I am setting the DataSourceID property instead of assigning it at runtime. I've tried it both ways, it doesn't seem to matter.

I'm not sure what else might be helpful, so just let me know if you need more details.

Now I'm left wondering if this might be the clue to my problem or if it's just a coincidence. If this is the key, I am too dense to figure it out. Does it all make sense to someone else?

+2


source to share


1 answer


As it turns out, the problem was in some code that I didn't think was worth posting. Every example I find seems to do something like this:



 Protected Overrides Function GetRootNodeCore() As System.Web.SiteMapNode
     Return siteRoot
 End Function

      

code>

It turns out that GetRootNodeCore () is called almost the same way directly from the gate, so sometimes siteRoot is nothing. So the solution looks like this:





Protected Overrides Function GetRootNodeCore() As System.Web.SiteMapNode
    If siteRoot Is Nothing Then
        SyncLock Me
            BuildSiteMap()
        End SyncLock
    End If

    Return siteRoot
End Function

      

code>

I won't admit that on my own, someone pointed this out to me: http://forums.asp.net/p/1473236/3420805.aspx#3420805

0


source







All Articles