MasterPageのASP.Net TreeViewコントロールが常に入力されるとは限りません
-
22-07-2019 - |
質問
私は初めての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