Pregunta

Estoy trabajando en mi primer proyecto ASP.Net, y parece que me arrojaron al fondo de inmediato. Todos los archivos de mi sitio se almacenan en una base de datos, por lo que estoy usando un VirtualPathProvider para acceder a ellos. Esa parte funciona bien, pero luego necesitaba un mapa del sitio que recogiera dinámicamente todos los archivos ya que el usuario agregará / eliminará archivos a medida que avanzan. Para hacer eso, creé una clase que hereda StaticSiteMapProvider, creé un SiteMapDataSource en mi página maestra y un TreeView para usarlo. En su mayor parte, esto funciona. Cuando carga la página, ve el TreeView y contiene todos los nodos que se supone que debe. Sin embargo, de vez en cuando TreeView está completamente en blanco, sin nodos en absoluto. Incluso copié TreeView en una página de contenido. La página de contenido TreeView siempre funciona, incluso cuando MasterPage no lo hace. (¡Tampoco sabía que un control en una página de contenido podría usar una fuente de datos en una página maestra hasta que olvidé copiar la fuente de datos!)

Intentando depurar eso, puse una excepción de lanzamiento en mi función BuildSiteMap () en SiteMapProvider solo para probarme a mí mismo que el código realmente se estaba ejecutando. Lo que encontré fue que la excepción fue golpeada cada vez. Sin embargo, el seguimiento de la pila no fue el mismo cada vez.

La mayoría de las veces, esto es lo que obtuve:

[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

Sin embargo, casi tan a menudo como TreeView se queda en blanco, obtuve esto:

    [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

Supongo que el bit de código útil sería la función 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 () y AddFiles () simplemente hacen más de lo mismo, así que por brevedad los dejaré fuera a menos que alguien piense que son importantes.

Traté de publicar el código para la vista de árbol aquí, pero parece que al sitio realmente no le gusta eso. Diré que estoy configurando la propiedad DataSourceID en lugar de asignarla en tiempo de ejecución. Lo intenté en ambos sentidos, no parece hacer la diferencia.

No estoy realmente seguro de qué más podría ser útil, así que avíseme si necesita más detalles.

Ahora me pregunto si esto podría ser una pista de mi problema o si es solo una coincidencia. Si es una pista, soy demasiado denso para entenderlo. ¿Algo de esto tiene sentido para alguien más?

¿Fue útil?

Solución

Como resultado, el problema estaba en un código que no creía que valiera la pena publicar. Parece que cada ejemplo que he encontrado hace algo como esto:

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

Resulta que GetRootNodeCore () se llama prácticamente desde el principio, por lo que a veces siteRoot no es nada. Entonces la solución es la siguiente:

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

    Return siteRoot
End Function

No me daré crédito por encontrar eso por mi cuenta, alguien me lo señaló aquí: http://forums.asp.net/p/1473236/3420805.aspx#3420805

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top