Il controllo ASP.Net TreeView su MasterPage non è sempre popolato
-
22-07-2019 - |
Domanda
Sto lavorando al mio primo progetto ASP.Net in assoluto, e mi sembra che sia stato lanciato subito nel profondo. Tutti i miei file del sito sono archiviati in un database, quindi sto usando un VirtualPathProvider per accedervi. Quella parte funziona bene, ma poi ho bisogno di una mappa del sito che raccolga dinamicamente tutti i file poiché l'utente aggiungerà / eliminerà i file mentre vanno. Per fare ciò, ho creato una classe che eredita StaticSiteMapProvider, ho creato un SiteMapDataSource sulla mia pagina master e un TreeView per usarlo. Per la maggior parte, funziona. Quando carichi la pagina vedi TreeView e contiene tutti i nodi che dovrebbe. Tuttavia, ogni tanto TreeView è completamente vuoto - nessun nodo. Ho persino copiato TreeView in una pagina di contenuti. La pagina dei contenuti TreeView funziona sempre, anche se MasterPage no. (Inoltre non sapevo che un controllo su una pagina di contenuto potesse usare un'origine dati su una pagina principale fino a quando mi sono dimenticato di copiare l'origine dati!)
Cercando di eseguire il debug, ho inserito un'eccezione di lancio nella mia funzione BuildSiteMap () in SiteMapProvider solo per dimostrare a me stesso che il codice era effettivamente in esecuzione. Quello che ho scoperto è che l'eccezione è stata colpita ogni volta. Tuttavia, la traccia dello stack non è stata la stessa ogni volta.
Il più delle volte, questo è quello che ho ottenuto:
[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
Tuttavia, ogni volta che TreeView si spegne, ho capito:
[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
Suppongo che l'utile bit di codice sarebbe la funzione 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 () e AddFiles () fanno semplicemente lo stesso, quindi per brevità li lascerò fuori a meno che qualcuno non pensi che siano importanti.
Ho provato a pubblicare il codice per il treeview qui, ma sembra che al sito non piaccia davvero. Dirò che sto impostando la proprietà DataSourceID invece di assegnarla in fase di esecuzione. L'ho provato in entrambi i modi, non sembra fare la differenza.
Non sono davvero sicuro di cos'altro potrebbe essere utile, quindi fammi sapere se hai bisogno di ulteriori dettagli.
Ora mi chiedo se questo potrebbe essere un indizio del mio problema o se è solo una coincidenza. Se è un indizio, sono troppo denso per capirlo. Qualcosa di tutto questo ha senso per qualcun altro?
Soluzione
A quanto pare, il problema era in un po 'di codice che non pensavo valesse la pena pubblicare. Sembra che ogni esempio che ho trovato faccia qualcosa del genere:
Protected Overrides Function GetRootNodeCore() As System.Web.SiteMapNode
Return siteRoot
End Function
Si scopre che GetRootNodeCore () viene chiamato praticamente dal gate, quindi a volte siteRoot non è nulla. Quindi la soluzione è la seguente:
Protected Overrides Function GetRootNodeCore() As System.Web.SiteMapNode
If siteRoot Is Nothing Then
SyncLock Me
BuildSiteMap()
End SyncLock
End If
Return siteRoot
End Function
Non mi prenderò il merito di averlo scoperto da solo, qualcuno me lo ha indicato qui: http://forums.asp.net/p/1473236/3420805.aspx#3420805