Pergunta

Eu estou trabalhando em meu primeiro projeto ASP.Net, e eu parecem ter sido jogado no fundo do poço imediatamente. Todos os meus arquivos do site são armazenados em um banco de dados, então eu estou usando um VirtualPathProvider para acessá-los. Essa parte funciona bem, mas então eu precisava de um mapa do site que dinamicamente pegar todos os arquivos desde que o usuário irá adicionar / apagar arquivos como eles vão. Para fazer isso, eu criei uma classe que herda StaticSiteMapProvider, criou um SiteMapDataSource na minha página mestra, e uma TreeView para usá-lo. Para a maior parte, isso funciona. Quando você carregar a página que você vê o TreeView e contém todos os nós que é suposto. No entanto, de vez em quando o TreeView é completamente em branco - nenhum nó em tudo. Eu até copiou o TreeView em uma página de conteúdo. O TreeView página de conteúdo sempre funciona, mesmo quando o MasterPage não. (Também eu não sabia um controle em uma página de conteúdo poderia usar uma fonte de dados em uma página mestre até que eu esqueci de copiar a fonte de dados!)

Tentando depurar isso, eu coloquei uma exceção de jogar na minha função BuildSiteMap () no SiteMapProvider só para provar a mim mesmo que o código foi realmente executado. O que descobri foi que a exceção foi atingido cada vez. No entanto, o rastreamento de pilha não era o mesmo de cada vez.

Na maioria das vezes, isso é o que eu tenho:

[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

No entanto, quase tão frequentemente como o TreeView viria para cima em branco, eu tenho esse:

    [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

Eu acho que o pouco útil de código seria a função 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 () apenas fazer mais do mesmo, então por razões de brevidade Vou deixá-los a menos que alguém pensa que eles são importantes.

Eu tentei postar o código para o treeview aqui, mas parece que o site realmente não gosto disso. Posso dizer que eu estou definindo a propriedade DataSourceID em vez de atribuí-la em tempo de execução. Eu tentei-o em ambos os sentidos, não parece fazer a diferença.

Eu não sou realmente certo o que mais pode ser útil, por isso, deixe-me saber se você precisar de mais detalhes.

Agora estou deixado querer saber se este poderia ser um indício para o meu problema ou se é apenas uma coincidência. Se é uma pista, eu sou demasiado denso para descobrir isso. Algum deste faz sentido para alguém?

Foi útil?

Solução

Como se vê, o problema estava em um pouco de código que eu não acho que foi pena postagem. Parece que todos os exemplos que eu encontrei faz algo parecido com isto:

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

Acontece que GetRootNodeCore () seja chamado praticamente fora direita do portão, por isso às vezes SiteRoot não é nada. Portanto, a solução é a seguinte:

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

    Return siteRoot
End Function

Eu não vou tomar o crédito para descobrir que no meu próprio, alguém apontou para mim aqui: http://forums.asp.net/p/1473236/3420805.aspx#3420805

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top