Dynamisches ändern der Titel des SiteMapNode
Haben wir eine website, verwendet eine Moor-standard-Standard-sitemap mit Sicherheit trimmen, wie folgt:
<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>
Alle sehr gut, aber eine Anfrage gekommen, um ändern Sie die Title
eines Knotens basierend auf einem back-end-Kriterien. Klingt wie eine einfache Sache, aber anscheinend nicht.
Versuch 1 - Umgang mit der SiteMapResolve
Veranstaltung. Es scheint keine Rolle wo dieses Ereignis wird abgewickelt, ich habe gezeigt, dass es in Global.asax
bloß weil das war einer der Orte, die ich versuchte es und es funktionierte.
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
Dies funktioniert gut, wenn die entsprechende Seite navigiert wurde, aber leider ist ein Teil der navigation auf der Website beinhaltet ein Kombinationsfeld, das Daten an die Website anzeigen wie diese:
<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" />
Wenn das Menü dargestellt wird, die SiteMapResolve
Ereignis nicht Feuer für den Inhalt, da der aktuelle Knoten ist die Seite, auf der das Menü definiert wird. Als ein Ergebnis, das Menü zeigt den Unsinn, den Platzhalter Titel aus der physikalischen XML-sitemap-Datei, anstatt den richtigen Titel.
Versuch 2 - Schreiben meiner eigenen sitemap-provider. Ich wollte nicht zu duplizieren, die Standard-Verhalten, also versuchte ich, die sich aus der Standard-Anbieter wie folgt.
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
Diese funktioniert nicht, da GetChildNodes
scheint nicht aufgerufen zu werden, sehr oft beim navigieren rund um die Website.
Versuch 3 - korrigieren Sie die Daten sofort, nachdem es in den Speicher geladen werden, sondern wenn auf Sie zugegriffen wird.
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
Diese scheint zu funktionieren. Allerdings bin ich besorgt über den Aufruf GetAllNodes
im BuildSiteMap
Methode. Es scheint mir falsch zu sein rekursiv ziehen Sie alle Daten in den Speicher nur zu reparieren, einen Wert. Auch habe ich keine Kontrolle darüber, Wann BuildSiteMap
genannt wird. Ich würde lieber etwas mehr wie Versuch 1, dass heißt auf Nachfrage, wenn der Knoten die ersten Daten erforderlich.
Versuch 4 (NEU) - Wie Versuch 2, aber überschreiben alle virtuelle Mitarbeiter, die mit Lesen zu tun Daten (CurrentNode
, FindSiteMapNode
, FindSiteMapNodeFromKey
, GetChildNodes
, GetCurrentNodeAndHintAncestorNodes
, GetCurrentNodeAndHintNeighborhoodNodes
, GetParentNode
, GetParentNodeRelativeToCurrentNodeAndHintDownFromParent
, GetParentNodeRelativeToNodeAndHintDownFromParent
, HintAncestorNodes
, HintNeighborhoodNodes
), versuchen abzufangen, das Lesen der dynamischen Knoten irgendwo.
Funktionierte dies nicht. Ich legte debug-Anweisungen in alle überschrieben Mitglieder, und es scheint, dass keiner von Ihnen überhaupt genannt werden, wenn Sie Datenbindung, um die dropdown-Liste. Die einzige Erklärung die ich mir denken kann ist, dass die Knoten alle in den Speicher gelesen, in einem Rutsch während der BuildSiteMap
nennen, so dass die SiteMapNode
ist nicht zu schlagen, die provider-Klasse beim auflisten von untergeordneten Knoten.
Hat jemand besser Vorschläge?
- Danke für deine ausführliche Frage gestellt. Es half einem ähnlichen Fall, die ich hatte!!!
Du musst angemeldet sein, um einen Kommentar abzugeben.
Custom-SiteMapProvider überschreiben wir die BuildSiteMap Methode und Konstrukt der SiteMapNodes manuell. Zu ändern und/oder hinzufügen von benutzerdefinierten Eigenschaften, die wir hinzufügen, benutzerdefinierte Attribute, um das SiteMapNodes durch erstellen einer NameValueCollection und fügen Sie diese übergeben, um die SiteMapNode Konstruktor.
Bist du ziemlich nah mit Versuch #2 - Sie müssen auch überschreiben GetParentNode und FindSiteMapNode als gut.
Vielen Dank an Mark und Rex für die Vorschläge. Was ich am Ende tun war das verlassen der sitemap-provider alleine und nur bis zur Festsetzung der Sie einen Knoten in der master-Seite, also:
Allerdings habe ich akzeptiert, Markieren Sie die Antwort, denn das ist, wie ich es tun werde, wenn es stellt sich heraus, dass umfangreichere änderungen gemacht werden müssen in Zukunft.
Dank Christian für Ihre Forschung. Verwenden Sie Ihre Ergebnisse, habe ich mit den folgenden, die den anderen helfen kann: