2

我正在处理我的第一个 ASP.Net 项目,我似乎马上就陷入了困境。我所有的站点文件都存储在数据库中,因此我使用 VirtualPathProvider 来访问它们。这部分工作得很好,但是我需要一个站点地图,它可以动态获取所有文件,因为用户将在他们去的时候添加/删除文件。为此,我创建了一个继承 StaticSiteMapProvider 的类,在我的母版页上创建了一个 SiteMapDataSource,以及一个使用它的 TreeView。在大多数情况下,这是可行的。当您加载页面时,您会看到 TreeView 并且它包含它应该包含的所有节点。但是,TreeView 时不时地是完全空白的——根本没有节点。我什至将 TreeView 复制到内容页面中。内容页面 TreeView 始终有效,即使 MasterPage 不可用。(我也没有

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

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

[例外:测试]
    c:\inetpub\wwwroot\App_Code\clsSiteMap.vb:49 中的 ADEM.clsSiteMap.BuildSiteMap()
    System.Web.StaticSiteMapProvider.GetChildNodes(SiteMapNode 节点) +54
    System.Web.SiteMapNode.get_ChildNodes() +27
    System.Web.UI.WebControls.SiteMapDataSource.GetNodes(SiteMapNode 节点)+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 节点) +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(布尔includeStagesBeforeAsyncPoint,布尔includeStagesAfterAsyncPoint)+842

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

    [例外:测试]
    c:\inetpub\wwwroot\App_Code\clsSiteMap.vb:49 中的 ADEM.clsSiteMap.BuildSiteMap()
    System.Web.StaticSiteMapProvider.FindSiteMapNode(字符串 rawUrl)+133
    System.Web.SiteMapProvider.FindSiteMapNode(HttpContext 上下文)+54
    System.Web.SiteMapProvider.get_CurrentNode() +35
    System.Web.UI.WebControls.TreeView.DataBindNode(TreeNode 节点)+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(布尔includeStagesBeforeAsyncPoint,布尔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

AddFolders() 和 AddFiles() 只是做更多相同的事情,所以为了简洁起见,我会将它们排除在外,除非有人认为它们很重要。

我试图在此处发布树视图的代码,但该网站似乎并不喜欢那样。我会说我正在设置 DataSourceID 属性,而不是在运行时分配它。两种方法我都试过了,好像没什么区别。

我不确定还有什么有用的,所以如果您需要更多详细信息,请告诉我。

现在我想知道这是否可能是我的问题的线索,或者这只是一个巧合。如果这是一个线索,我太密集了,无法弄清楚。这对其他人有意义吗?

4

1 回答 1

0

事实证明,问题在于我认为不值得发布的一些代码。似乎我发现的每个示例都执行以下操作:

 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

于 2009-09-23T12:46:17.717 回答