Элемент управления ASP.Net TreeView на MasterPage не всегда заполнен

StackOverflow https://stackoverflow.com/questions/1446691

Вопрос

Я работаю над своим первым проектом ASP.Net, и мне кажется, что меня сразу бросили в глубокий конец. Все файлы моего сайта хранятся в базе данных, поэтому я использую VirtualPathProvider для доступа к ним. Эта часть работает хорошо, но тогда мне понадобилась карта сайта, которая будет динамически подбирать все файлы, так как пользователь будет добавлять / удалять файлы по мере их поступления. Для этого я создал класс, который наследует StaticSiteMapProvider, создал SiteMapDataSource на моей мастер-странице и TreeView для его использования. По большей части это работает. Когда вы загружаете страницу, вы видите TreeView, и он содержит все узлы, которые он должен. Тем не менее, время от времени TreeView полностью пуст - никаких узлов вообще нет. Я даже скопировал TreeView на страницу контента. Страница содержимого TreeView всегда работает, даже если MasterPage не работает. (Также я не знал, что элемент управления на странице содержимого может использовать источник данных на главной странице, пока я не забуду скопировать источник данных!)

Пытаясь отладить это, я поместил исключение throw в мою функцию BuildSiteMap () в SiteMapProvider, просто чтобы доказать себе, что код действительно выполняется. Я обнаружил, что исключение было совершено каждый раз. Однако трассировка стека не всегда была одинаковой.

Большую часть времени это то, что я получил:

[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

Однако примерно так же часто, как TreeView будет пустым, я получил следующее:

    [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

Полагаю, полезным фрагментом кода была бы функция 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 () и AddFiles () просто делают больше того же самого, поэтому для краткости я их опущу, если кто-то не считает их важными.

Я попытался опубликовать здесь код для дерева, но, похоже, сайту это не очень нравится. Я скажу, что я устанавливаю свойство DataSourceID вместо назначения его во время выполнения. Я пробовал оба пути, похоже, ничего не изменилось.

Я не совсем уверен, что еще может быть полезно, поэтому просто дайте мне знать, если вам нужно больше подробностей.

Теперь мне остается только подумать, может ли это быть ключом к моей проблеме или это просто совпадение. Если это подсказка, я слишком глуп, чтобы понять это. Имеет ли это какое-то значение для кого-то еще?

Это было полезно?

Решение

Как выяснилось, проблема заключалась в небольшом количестве кода, который, как я думал, не стоил публиковать. Кажется, что каждый пример, который я нашел, делает что-то вроде этого:

<код>

<код>
 Protected Overrides Function GetRootNodeCore() As System.Web.SiteMapNode
     Return siteRoot
 End Function

<код>

Оказывается, что GetRootNodeCore () вызывается почти сразу же, поэтому иногда siteRoot - ничто. Таким образом, решение заключается в следующем:

<код>

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

    Return siteRoot
End Function

<код>

Я не возьму на себя ответственность за то, что нашел это самостоятельно, кто-то указал мне здесь: http://forums.asp.net/p/1473236/3420805.aspx#3420805

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top