Question

Je suis en train de travailler sur mon tout premier projet ASP.Net, et il semble que je sois tombé dans le vif du sujet tout de suite. Tous les fichiers de mon site sont stockés dans une base de données, j'utilise donc un VirtualPathProvider pour y accéder. Cette partie fonctionne bien, mais il me fallait alors un plan du site qui récupère de manière dynamique tous les fichiers, car l'utilisateur ajoute / supprime des fichiers au fur et à mesure. Pour ce faire, j'ai créé une classe qui hérite de StaticSiteMapProvider, créé un SiteMapDataSource sur ma page maître et un TreeView pour l'utiliser. Pour la plupart, cela fonctionne. Lorsque vous chargez la page, vous voyez TreeView et il contient tous les nœuds auxquels il est censé être associé. Cependant, de temps en temps, TreeView est complètement vide - pas de nœuds du tout. J'ai même copié le TreeView dans une page de contenu. La page de contenu TreeView fonctionne toujours, même lorsque MasterPage ne fonctionne pas. (En outre, je ne savais pas qu'un contrôle sur une page de contenu pouvait utiliser une source de données sur une page maître jusqu'à ce que j'oublie de copier la source de données!)

En essayant de déboguer cela, je mets une exception de projection dans ma fonction BuildSiteMap () dans SiteMapProvider, juste pour me prouver que le code était en cours d'exécution. Ce que j'ai trouvé, c'est que l'exception a été touchée à chaque fois. Cependant, la trace de la pile n’est pas toujours la même.

La plupart du temps, voici ce que j'ai eu:

[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

Cependant, à peu près aussi souvent que TreeView venait à blanc, j'ai ceci:

    [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

Je suppose que le bit de code utile serait la fonction 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 () et AddFiles () font juste plus de la même chose, donc par souci de brièveté, je les laisserai tomber sauf si quelqu'un pense qu'ils sont importants.

J'ai essayé de poster le code de l'arborescence ici, mais il semble que le site n'aime pas vraiment cela. Je dirai que je mets la propriété DataSourceID au lieu de l'attribuer à l'exécution. Je l'ai essayé dans les deux sens, ne semble pas faire de différence.

Je ne suis pas vraiment sûr de ce qui pourrait être utile, alors laissez-moi savoir si vous avez besoin de plus de détails.

Maintenant, je me demande si cela pourrait être un indice de mon problème ou s'il ne s'agit que d'une coïncidence. Si c'est un indice, je suis trop dense pour le comprendre. Est-ce que cela a du sens pour quelqu'un d'autre?

Était-ce utile?

La solution

Il s’est avéré que le problème tenait à un peu de code qui, à mon avis, ne valait pas la peine d’être publié. Il semble que chaque exemple que j'ai trouvé fasse quelque chose comme ceci:

 Protected Overrides Function GetRootNodeCore() As System.Web.SiteMapNode
     Return siteRoot
 End Function

Il se trouve que GetRootNodeCore () est appelé assez rapidement, donc parfois, siteRoot n’est rien. La solution est donc la suivante:

Protected Overrides Function GetRootNodeCore() As System.Web.SiteMapNode
    If siteRoot Is Nothing Then
        SyncLock Me
            BuildSiteMap()
        End SyncLock
    End If

    Return siteRoot
End Function

Je ne prendrai pas le mérite de l'avoir découvert seul, quelqu'un me l'a fait remarquer ici: http://forums.asp.net/p/1473236/3420805.aspx#3420805

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top