我們使用一個沼澤標準的默認地圖與安全修整作爲一個網站如下:的動態調整的SiteMapNode的標題
<siteMap defaultProvider="default" enabled="true">
<providers>
<add siteMapFile="~/Web.sitemap" securityTrimmingEnabled="true" name="default" type="System.Web.XmlSiteMapProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</providers>
</siteMap>
一切都非常好,但要求已經到了改變的Title
一個節點基於一些後端標準。聽起來很簡單,但顯然不是。
嘗試1 - 處理SiteMapResolve
事件。它似乎並不重要,其中這個事件處理,我已經在Global.asax
顯示它,僅僅是因爲那是我試過它的地方之一,它的工作。
Public Class Global_asax
Inherits System.Web.HttpApplication
Sub Application_BeginRequest(ByVal sender As Object, ByVal e As EventArgs)
AddHandler SiteMap.SiteMapResolve, AddressOf SiteMapResolve
End Sub
Sub Application_EndRequest(ByVal sender As Object, ByVal e As EventArgs)
RemoveHandler SiteMap.SiteMapResolve, AddressOf SiteMapResolve
End Sub
Private Shared Function SiteMapResolve(ByVal sender As Object, ByVal e As SiteMapResolveEventArgs) As SiteMapNode
Dim node As SiteMapNode = SiteMap.CurrentNode
If IsThisTheNodeToChange(node) Then
node = node.Clone()
node.Title = GetNodeTitle()
End If
Return node
End Function
End Class
這工作得很好時,相關頁面被導航到,但該網站的導航不幸的是部分涉及一個組合框,是數據綁定到站點地圖是這樣的:
<asp:SiteMapDataSource ID="siteMapDataSource" runat="Server" ShowStartingNode="false" StartFromCurrentNode="false" StartingNodeOffset="1" />
<asp:DropDownList ID="pageMenu" runat="Server" AutoPostBack="True" DataSourceID="siteMapDataSource" DataTextField="Title" DataValueField="Url" />
當這菜單被渲染時,SiteMapResolve
事件不會觸發任何內容,因爲當前節點是定義菜單的頁面。因此,菜單顯示的是物理站點地圖文件中的無意義佔位符標題,而不是正確的標題。
嘗試2 - 寫我自己的網站地圖提供商。我不想重複所有的默認行爲,所以我嘗試從默認提供者派生,如下所示。
Public Class DynamicXmlSiteMapProvider
Inherits XmlSiteMapProvider
Private _dataFixedUp As Boolean = False
Public Overrides Function GetChildNodes(ByVal node As SiteMapNode) As SiteMapNodeCollection
Dim result As SiteMapNodeCollection = MyBase.GetChildNodes(node)
If Not _dataFixedUp Then
For Each childNode As SiteMapNode In result
FixUpNode(childNode)
Next
End If
Return result
End Function
Private Sub FixUpNode(ByVal node As SiteMapNode)
If IsThisTheNodeToChange(node) Then
node.ReadOnly = False
node.Title = GetNodeTitle()
node.ReadOnly = True
_dataFixedUp = True
End If
End Sub
End Class
因爲GetChildNodes
沒有出現在工地附近航行時要調用很多時候這是行不通的。
嘗試3 - 嘗試在數據加載到內存後立即修復數據,而不是在訪問數據時修復。
Public Class DynamicXmlSiteMapProvider
Inherits XmlSiteMapProvider
Private _dataFixInProgress As Boolean = False
Private _dataFixDone As Boolean = False
Public Overrides Function BuildSiteMap() As SiteMapNode
Dim result As SiteMapNode = MyBase.BuildSiteMap()
If Not _dataFixInProgress AndAlso Not _dataFixDone Then
_dataFixInProgress = True
For Each childNode As SiteMapNode In result.GetAllNodes()
FixUpNode(childNode)
Next
_dataFixInProgress = False
_dataFixDone = True
End If
Return result
End Function
Private Sub FixUpNode(ByVal node As SiteMapNode)
If IsThisTheNodeToChange(node) Then
node.ReadOnly = False
node.Title = GetNodeTitle()
node.ReadOnly = True
End If
End Sub
End Class
這似乎工作。不過,我很擔心在BuildSiteMap
方法中致電GetAllNodes
。我只是爲了修正一個值而遞歸地將所有數據拉入內存似乎是錯誤的。另外,我無法控制何時調用BuildSiteMap
。我更喜歡更像是嘗試1的東西,當第一次需要節點數據時,它是按需調用的。
嘗試4(NEW) - 像嘗試2,但壓倒一切的所有虛擬成員是與讀取數據(CurrentNode
,FindSiteMapNode
,FindSiteMapNodeFromKey
,GetChildNodes
,GetCurrentNodeAndHintAncestorNodes
,GetCurrentNodeAndHintNeighborhoodNodes
,GetParentNode
,GetParentNodeRelativeToCurrentNodeAndHintDownFromParent
,GetParentNodeRelativeToNodeAndHintDownFromParent
,HintAncestorNodes
做,HintNeighborhoodNodes
),試圖攔截某處動態節點的讀數。
這沒有奏效。我在所有重寫的成員中都放置了調試語句,並且在數據綁定到下拉列表時,似乎根本沒有人調用它們。我能想到的唯一解釋是節點在調用BuildSiteMap
期間一次都被讀入內存,因此在枚舉子節點時SiteMapNode
未觸及提供程序類。
有沒有人有更好的建議?
感謝您的詳細質疑。它幫助了我有類似的情況! – danyim 2011-11-03 16:34:12