MasterPageのASP.Net TreeViewコントロールが常に入力されるとは限りません

StackOverflow https://stackoverflow.com/questions/1446691

質問

私は初めてのASP.Netプロジェクトに取り組んでいますが、すぐに深層に投げ込まれたようです。すべてのサイトファイルはデータベースに格納されているため、VirtualPathProviderを使用してそれらにアクセスしています。その部分はうまく機能しますが、ユーザーがファイルを追加/削除するため、すべてのファイルを動的に取得するサイトマップが必要でした。そのために、StaticSiteMapProviderを継承するクラスを作成し、マスターページにSiteMapDataSourceを作成し、それを使用するTreeViewを作成しました。ほとんどの場合、これは機能します。ページをロードすると、TreeViewが表示され、想定されているすべてのノードが含まれます。ただし、ときどきTreeViewは完全に空白になり、ノードはまったくありません。 TreeViewをコンテンツページにコピーしました。 MasterPageが機能しない場合でも、コンテンツページTreeViewは常に機能します。 (また、データソースのコピーを忘れるまで、コンテンツページのコントロールがマスターページのデータソースを使用できることを知りませんでした!)

それをデバッグするために、SiteMapProviderのBuildSiteMap()関数にthrow例外を入れて、コードが実際に実行されていることを証明しました。私が見つけたのは、例外が毎回ヒットしたことです。ただし、スタックトレースは毎回同じではありませんでした。

ほとんどの場合、これは私が得たものです:

[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

AddFolders()とAddFiles()は同じことを行うだけなので、簡潔にするために、誰かが重要だと思わない限り、それらを省きます。

ツリービューのコードをここに投稿しようとしましたが、サイトはそれを好まないようです。実行時に割り当てるのではなく、DataSourceIDプロパティを設定すると言います。両方の方法で試しましたが、違いはないようです。

他に何が役立つのかよくわかりません。詳細が必要な場合はお知らせください。

今、これが私の問題の手掛かりなのか、それとも単なる偶然なのか疑問に思っています。それが手がかりである場合、私はそれを理解するには密度が高すぎます。これは他の誰かにとって意味がありますか?

役に立ちましたか?

解決

判明したように、問題は、投稿する価値があるとは思わなかったコードにありました。私が見つけたすべての例はこのようなことをしているようです:

 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

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top