如何隐藏节点,使其不出现在菜单上而不是面包屑上(使用 SqlSiteMapProvider)
-
27-09-2019 - |
题
我在用 邪恶的代码 sqlsitemapprovider 或者 这是VB版本. 。大多数事情都会顺利进行!但是,当我想隐藏一些节点,使其不出现在菜单上,同时保持显示在站点地图路径上时,我无法弄清楚。我尝试更改 sqlsitemapprovider 代码但没有成功。我已经发现 大卫·萨斯曼的 (来自sp.net)答案。但它是针对 .sitemap 文件的。那么我怎样才能对上面提到的 sql 站点地图提供程序执行相同的操作呢?
我添加了一个名为“visible”的列到我的 SiteMap 表中,它的类型是“bit”,然后我完成了这些更改(抱歉代码太长):
Imports System
Imports System.Web
Imports System.Data.SqlClient
Imports System.Collections.Specialized
Imports System.Configuration
Imports System.Web.Configuration
Imports System.Collections.Generic
Imports System.Configuration.Provider
Imports System.Security.Permissions
Imports System.Data.Common
Imports System.Data
Imports System.Web.Caching
''' <summary>
''' Summary description for SqlSiteMapProvider
''' </summary>
<SqlClientPermission(SecurityAction.Demand, Unrestricted:=True)> _
Public Class SqlSiteMapProvider
Inherits StaticSiteMapProvider
Private Const _errmsg1 As String = "Basamak no bulunamadı"
Private Const _errmsg2 As String = "Çift Basamak No"
Private Const _errmsg3 As String = "Üst Basamak Bulunamadı"
Private Const _errmsg4 As String = "Hatalı Üst Basamak"
Private Const _errmsg5 As String = "Bağlantı dizesi bulunamadı veya boş"
Private Const _errmsg6 As String = "Bağlantı dizesi bulunamadı"
Private Const _errmsg7 As String = "Bağlantı dizesi boş"
Private Const _errmsg8 As String = "Hatalı sqlCacheDependency"
Private Const _cacheDependencyName As String = "__SiteMapCacheDependency"
Private _connect As String
'Database connection string
Private _database As String, _table As String
'Database info for SQL Server 7/2000 cache dependency
Private _2005dependency As Boolean = False
'Database info for SQL Server 2005 cache dependency
Private _indexID As Integer, _indexTitle As Integer, _indexUrl As Integer, _indexDesc As Integer, _indexRoles As Integer, _indexParent As Integer, _indexvisible As Boolean
Private _nodes As New Dictionary(Of Integer, SiteMapNode)(16)
Private ReadOnly _lock As New Object()
Private _root As SiteMapNode
'Added...Declare an arraylist to hold all the roles this menu item applies to
Public roles As New ArrayList
Public Overloads Overrides Sub Initialize(ByVal name As String, ByVal config As NameValueCollection)
'Verify that config isn't null
If config Is Nothing Then
Throw New ArgumentNullException("config")
End If
'Assign the provider a default name if it doesn't have one
If [String].IsNullOrEmpty(Name) Then
Name = "SqlSiteMapProvider"
End If
' Add a default "description" attribute to config if the
' attribute doesnt exist or is empty
If String.IsNullOrEmpty(config("description")) Then
config.Remove("description")
config.Add("description", "SQL site map provider")
End If
' Call the base class's Initialize method
MyBase.Initialize(Name, config)
' Initialize _connect
Dim connect As String = config("connectionStringName")
If [String].IsNullOrEmpty(connect) Then
Throw New ProviderException(_errmsg5)
End If
config.Remove("connectionStringName")
If WebConfigurationManager.ConnectionStrings(connect) Is Nothing Then
Throw New ProviderException(_errmsg6)
End If
_connect = WebConfigurationManager.ConnectionStrings(connect).ConnectionString
If [String].IsNullOrEmpty(_connect) Then
Throw New ProviderException(_errmsg7)
End If
' Initialize SQL cache dependency info
Dim dependency As String = config("sqlCacheDependency")
If Not [String].IsNullOrEmpty(dependency) Then
If [String].Equals(dependency, "CommandNotification", StringComparison.InvariantCultureIgnoreCase) Then
SqlDependency.Start(_connect)
_2005dependency = True
Else
' If not "CommandNotification", then extract database and table names
Dim info As String() = dependency.Split(New Char() {":"c})
If info.Length <> 2 Then
Throw New ProviderException(_errmsg8)
End If
_database = info(0)
_table = info(1)
End If
config.Remove("sqlCacheDependency")
End If
' SiteMapProvider processes the securityTrimmingEnabled
' attribute but fails to remove it. Remove it now so we can
' check for unrecognized configuration attributes.
If config("securityTrimmingEnabled") IsNot Nothing Then
config.Remove("securityTrimmingEnabled")
End If
' Throw an exception if unrecognized attributes remain
If config.Count > 0 Then
Dim attr As String = config.GetKey(0)
If Not [String].IsNullOrEmpty(attr) Then
Throw New ProviderException("Unrecognized attribute: " + attr)
End If
End If
End Sub
Public Overloads Overrides Function BuildSiteMap() As SiteMapNode
SyncLock _lock
' Return immediately if this method has been called before
If _root IsNot Nothing Then
Return _root
End If
' Query the database for site map nodes
Dim connection As New SqlConnection(_connect)
Try
Dim command As New SqlCommand("proc_GetSiteMap", connection)
command.CommandType = CommandType.StoredProcedure
' Create a SQL cache dependency if requested
Dim dependency As SqlCacheDependency = Nothing
If _2005dependency Then
dependency = New SqlCacheDependency(command)
ElseIf Not [String].IsNullOrEmpty(_database) AndAlso Not String.IsNullOrEmpty(_table) Then
dependency = New SqlCacheDependency(_database, _table)
End If
connection.Open()
Dim reader As SqlDataReader = command.ExecuteReader()
_indexID = reader.GetOrdinal("ID")
_indexUrl = reader.GetOrdinal("Url")
_indexTitle = reader.GetOrdinal("Title")
_indexDesc = reader.GetOrdinal("Description")
_indexRoles = reader.GetOrdinal("Roles")
_indexParent = reader.GetOrdinal("Parent")
_indexvisible = reader.GetOrdinal("visible")
If reader.Read() Then
' Create the root SiteMapNode and add it to the site map
_root = CreateSiteMapNodeFromDataReader(reader)
AddNode(_root, Nothing)
' Build a tree of SiteMapNodes underneath the root node
While reader.Read()
' Create another site map node and add it to the site map
Dim node As SiteMapNode = CreateSiteMapNodeFromDataReader(reader)
AddNode(node, GetParentNodeFromDataReader(reader))
End While
' Use the SQL cache dependency
If dependency IsNot Nothing Then
HttpRuntime.Cache.Insert(_cacheDependencyName, New Object(), dependency, Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, CacheItemPriority.NotRemovable, _
New CacheItemRemovedCallback(AddressOf OnSiteMapChanged))
End If
End If
Finally
connection.Close()
End Try
' Return the root SiteMapNode
Return _root
End SyncLock
End Function
Protected Overloads Overrides Function GetRootNodeCore() As SiteMapNode
SyncLock _lock
BuildSiteMap()
Return _root
End SyncLock
End Function
' Helper methods
Private Function CreateSiteMapNodeFromDataReader(ByVal reader As DbDataReader) As SiteMapNode
' Make sure the node ID is present
If reader.IsDBNull(_indexID) Then
Throw New ProviderException(_errmsg1)
End If
' Get the node ID from the DataReader
Dim id As Integer = reader.GetInt32(_indexID)
' Make sure the node ID is unique
If _nodes.ContainsKey(id) Then
Throw New ProviderException(_errmsg2)
End If
' Get title, URL, description, and roles from the DataReader
Dim title As String = IIf(reader.IsDBNull(_indexTitle), Nothing, reader.GetString(_indexTitle).Trim())
'Dim url As String = IIf(reader.IsDBNull(_indexUrl), Nothing, reader.GetString(_indexUrl).Trim())
'Dim url As String = ReplaceNullRefs(reader, _indexUrl)
Dim url As String = String.Empty
If Not (reader.IsDBNull(_indexUrl)) Then
url = reader.GetString(_indexUrl).Trim()
Else
url = ""
End If
'Eliminated...see http://weblogs.asp.net/psteele/archive/2003/10/09/31250.aspx
'Dim description As String = IIf(reader.IsDBNull(_indexDesc), Nothing, reader.GetString(_indexDesc).Trim())
'Added line below and 'ReplaceNUllRefs' func
Dim description As String = ReplaceNullRefs(reader, _indexDesc)
'Changed variable name from 'roles' to 'rolesN' and added line 230 to dump all roles into an arrayList
Dim rolesN As String = IIf(reader.IsDBNull(_indexRoles), Nothing, reader.GetString(_indexRoles).Trim())
Dim rolelist As String() = Nothing
If Not [String].IsNullOrEmpty(rolesN) Then
rolelist = rolesN.Split(New Char() {","c, ";"c}, 512)
End If
roles = ArrayList.Adapter(rolelist)
Dim visible As Boolean = ReplaceNullRefs(reader, _indexvisible)
' Create a SiteMapNode
Dim node As New SiteMapNode(Me, id.ToString(), url, title, description, rolelist, _
Nothing, Nothing, Nothing)
' Record the node in the _nodes dictionary
_nodes.Add(id, node)
' Return the node
Return node
End Function
Private Function ReplaceNullRefs(ByVal rdr As SqlDataReader, ByVal rdrVal As Integer) As String
If Not (rdr.IsDBNull(rdrVal)) Then
Return rdr.GetString(rdrVal)
Else
Return String.Empty
End If
End Function
Private Function GetParentNodeFromDataReader(ByVal reader As DbDataReader) As SiteMapNode
' Make sure the parent ID is present
If reader.IsDBNull(_indexParent) Then
'**** Commented out throw, added exit function ****
Throw New ProviderException(_errmsg3)
'Exit Function
End If
' Get the parent ID from the DataReader
Dim pid As Integer = reader.GetInt32(_indexParent)
' Make sure the parent ID is valid
If Not _nodes.ContainsKey(pid) Then
Throw New ProviderException(_errmsg4)
End If
' Return the parent SiteMapNode
Return _nodes(pid)
End Function
Private Sub OnSiteMapChanged(ByVal key As String, ByVal item As Object, ByVal reason As CacheItemRemovedReason)
SyncLock _lock
If key = _cacheDependencyName AndAlso reason = CacheItemRemovedReason.DependencyChanged Then
' Refresh the site map
Clear()
_nodes.Clear()
_root = Nothing
End If
End SyncLock
End Sub
End Class
我收到此错误:
*Özel Durum Ayrıntıları: System.IndexOutOfRangeException: visible
Kaynak Hatası:
Satır 154: _indexRoles = reader.GetOrdinal("Roles")
Satır 155: _indexParent = reader.GetOrdinal("Parent")
Satır 156: _indexvisible = reader.GetOrdinal("visible")
Satır 157:
Satır 158: If reader.Read() Then
Kaynak Dosya: D:\Websites\kaihl\App_Code\SqlSiteMapProvider.vb Satır: 156*
我想要的是告诉 sqlsitemapprovider 在每个 sitemapnode 中包含一个名为visible =“true/false”的属性。由于这将是 sitemappath 和菜单的额外属性(我认为),此代码将在菜单中而不是面包屑中执行隐藏工作(根据 David Sussman 对类似文件 .sitemap 的线程的回复,如我在上面的问题中链接的那样) :
Protected Sub Menu1_MenuItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.MenuEventArgs) Handles Menu1.MenuItemDataBound
Dim node As SiteMapNode = CType(e.Item.DataItem, SiteMapNode)
' check for the visible attribute and if false
' remove the node from the parent
' this allows nodes to appear in the SiteMapPath but not show on the menu
If Not String.IsNullOrEmpty(node("visible")) Then
Dim isVisible As Boolean
If Boolean.TryParse(node("visible"), isVisible) Then
If Not isVisible Then
e.Item.Parent.ChildItems.Remove(e.Item)
End If
End If
End If
End Sub
如何实现这一目标?谢谢。
更新:我发现了一些非常接近的东西此页 但仍然无法部署解决方案。
Dim atts As NameValueCollection = Nothing
Dim attributeString As String = reader("attributes").ToString().Trim()
If Not String.IsNullOrEmpty(attributeString) Then
atts = New NameValueCollection()
Dim attributePairs() As String = attributeString.Split(";")
For Each attributePair As String In atts
Dim attributes() As String = attributePair.Split(":")
If attributes.Length = 2 Then
atts.Add(atts(0), attributes(1))
End If
Next
End If
Dim node As New SiteMapNode(Me, id.ToString(), url, title, description, rolelist, _
atts, Nothing, Nothing)
其他提示
结账这个 关联. 。他覆盖了 SiteMapprovider 上的 IsAccessibleToUser 属性,以根据当前用户的角色有选择地显示节点。您可以更改条件以满足您的需要。
不隶属于 StackOverflow