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?

È stato utile?

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

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top