我正在开展我的第一个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属性而不是在运行时分配它。我尝试了两种方式,似乎没有什么区别。
我不确定还有什么可能有用,所以如果您需要更多细节,请告诉我。
现在我想知道这是否可以解决我的问题,或者这只是巧合。如果这是一个线索,我太密集了,无法弄明白。这对任何人都有意义吗?
答案 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