主页上的ASP.Net TreeView控件并不总是填充

时间:2009-09-18 20:31:15

标签: asp.net treeview sitemapprovider

我正在开展我的第一个ASP.Net项目,而且我似乎已经被抛到了深处。我的所有站点文件都存储在数据库中,因此我使用VirtualPathProvider来访问它们。这部分效果很好,但后来我需要一个能够动态获取所有文件的站点地图,因为用户会随时添加/删除文件。为此,我创建了一个继承StaticSiteMapProvider的类,在我的母版页上创建了一个SiteMapDataSource,并使用了TreeView来使用它。在大多数情况下,这是有效的。当您加载页面时,您会看到TreeView,它包含它应该具有的所有节点。但是,TreeView时不时都是空白的 - 根本没有节点。我甚至将TreeView复制到了内容页面中。内容页面TreeView始终有效,即使MasterPage没有。 (另外我不知道内容页面上的控件可能会在母版页上使用数据源,直到我忘记复制数据源!)

尝试调试它,我在SiteMapProvider的BuildSiteMap()函数中添加了抛出异常,只是为了向自己证明代码实际上正在运行。我发现每次都会遇到异常。但是,堆栈跟踪每次都不一样。

大多数时候,这就是我所得到的:

[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

然而,就像TreeView一样空白,我得到了这个:

    [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

我想代码的有用位将是BuildSiteMap函数:

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

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

AddFolders()和AddFiles()只是做了同样的事情,所以为了简洁起见,除非有人认为它们很重要,否则我会把它们留下来。

我试图在这里发布树视图的代码,但似乎网站并不是那么喜欢。我会说我正在设置DataSourceID属性而不是在运行时分配它。我尝试了两种方式,似乎没有什么区别。

我不确定还有什么可能有用,所以如果您需要更多细节,请告诉我。

现在我想知道这是否可以解决我的问题,或者这只是巧合。如果这是一个线索,我太密集了,无法弄明白。这对任何人都有意义吗?

1 个答案:

答案 0 :(得分:0)

事实证明,问题在于我认为不值得发布的一些代码。似乎我发现的每个例子都是这样的:

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

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

事实证明GetRootNodeCore()几乎被调出门,所以有时siteRoot什么都没有。所以解决方案如下:

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

    Return siteRoot
End Function

我不会因为在我自己身上发现这一点而感到荣幸:http://forums.asp.net/p/1473236/3420805.aspx#3420805