StaticSiteMapProvider 类
定义
重要
一些信息与预发行产品相关,相应产品在发行之前可能会进行重大修改。 对于此处提供的信息,Microsoft 不作任何明示或暗示的担保。
作为 SiteMapProvider 抽象类的部分实现和 XmlSiteMapProvider 类(它是 ASP.NET 中的默认站点地图提供程序)的基类。
public ref class StaticSiteMapProvider abstract : System::Web::SiteMapProvider
public abstract class StaticSiteMapProvider : System.Web.SiteMapProvider
type StaticSiteMapProvider = class
inherit SiteMapProvider
Public MustInherit Class StaticSiteMapProvider
Inherits SiteMapProvider
- 继承
- 派生
示例
下面的代码示例演示如何扩展 类以 StaticSiteMapProvider 将 Microsoft Access 用作站点地图提供程序。 类 AccessSiteMapProvider
是一个站点地图提供程序,仅支持简单的一级深层层次结构。 存储站点地图数据的表具有以下结构:
NODEID URL NAME PARENTNODEID
---------------------------------------------
1 default.aspx Default <NULL>
2 catalog.aspx Catalog 1
3 aboutus.aspx Contact Us 1
...
类 AccessSiteMapProvider
派生自 类, StaticSiteMapProvider 并使用基本 SQL 查询和 OleDbCommand 和 OleDbDataReader 对象从 Microsoft Access 数据库检索其信息。
#using <System.Data.dll>
#using <System.Transactions.dll>
#using <System.EnterpriseServices.dll>
#using <System.dll>
#using <System.Web.dll>
#using <System.Configuration.dll>
using namespace System;
using namespace System::Collections;
using namespace System::Collections::Specialized;
using namespace System::Configuration;
using namespace System::Data;
using namespace System::Data::OleDb;
using namespace System::Security::Permissions;
using namespace System::Web;
/// An extremely simple AccessSiteMapProvider that only supports a
/// site map node hierarchy 1 level deep.
[AspNetHostingPermission(SecurityAction::Demand,Level=AspNetHostingPermissionLevel::Minimal)]
public ref class AccessSiteMapProvider: public StaticSiteMapProvider
{
private:
SiteMapNode ^ rootNode;
OleDbConnection^ accessConnection;
// This string is case sensitive.
String^ AccessConnectionStringName;
public:
// Implement a default constructor.
AccessSiteMapProvider()
{
initialized = false;
AccessConnectionStringName = "accessSiteMapConnectionString";
}
private:
// Some basic state to help track the initialization state of the provider.
bool initialized;
public:
property bool IsInitialized
{
virtual bool get()
{
return initialized;
}
}
property SiteMapNode ^ RootNode
{
// Return the root node of the current site map.
virtual SiteMapNode ^ get() override
{
SiteMapNode ^ temp = nullptr;
temp = BuildSiteMap();
return temp;
}
}
protected:
virtual SiteMapNode ^ GetRootNodeCore() override
{
return RootNode;
}
public:
// Initialize is used to initialize the properties and any state that the
// AccessProvider holds, but is not used to build the site map.
// The site map is built when the BuildSiteMap method is called.
virtual void Initialize( String^ name, NameValueCollection^ attributes ) override
{
if ( IsInitialized )
return;
StaticSiteMapProvider::Initialize( name, attributes );
// Create and test the connection to the Microsoft Access database.
// Retrieve the Value of the Access connection string from the
// attributes NameValueCollection.
String^ connectionString = attributes[ AccessConnectionStringName ];
if ( nullptr == connectionString || connectionString->Length == 0 )
throw gcnew Exception( "The connection string was not found." );
else
accessConnection = gcnew OleDbConnection( connectionString );
initialized = true;
}
protected:
///
/// SiteMapProvider and StaticSiteMapProvider methods that this derived class must override.
///
// Clean up any collections or other state that an instance of this may hold.
virtual void Clear() override
{
System::Threading::Monitor::Enter( this );
try
{
rootNode = nullptr;
StaticSiteMapProvider::Clear();
}
finally
{
System::Threading::Monitor::Exit( this );
}
}
public:
// Build an in-memory representation from persistent
// storage, and return the root node of the site map.
virtual SiteMapNode ^ BuildSiteMap() override
{
// Since the SiteMap class is static, make sure that it is
// not modified while the site map is built.
System::Threading::Monitor::Enter( this );
try
{
// If there is no initialization, this method is being
// called out of order.
if ( !IsInitialized )
{
throw gcnew Exception( "BuildSiteMap called incorrectly." );
}
// If there is no root node, then there is no site map.
if ( nullptr == rootNode )
{
// Start with a clean slate
Clear();
// Select the root node of the site map from Microsoft Access.
int rootNodeId = -1;
if ( accessConnection->State == ConnectionState::Closed )
accessConnection->Open();
OleDbCommand^ rootNodeCommand = gcnew OleDbCommand
("SELECT nodeid, url, name FROM SiteMap WHERE parentnodeid IS NULL", accessConnection);
OleDbDataReader^ rootNodeReader = rootNodeCommand->ExecuteReader();
if ( rootNodeReader->HasRows )
{
rootNodeReader->Read();
rootNodeId = rootNodeReader->GetInt32( 0 );
// Create a SiteMapNode that references the current StaticSiteMapProvider.
rootNode = gcnew SiteMapNode(this, rootNodeId.ToString(),
rootNodeReader->GetString( 1 ),rootNodeReader->GetString( 2 ));
}
else
return nullptr;
rootNodeReader->Close();
// Select the child nodes of the root node.
OleDbCommand^ childNodesCommand = gcnew OleDbCommand
("SELECT nodeid, url, name FROM SiteMap WHERE parentnodeid = ?", accessConnection);
OleDbParameter^ rootParam = gcnew OleDbParameter( "parentid", OleDbType::Integer);
rootParam->Value = rootNodeId;
childNodesCommand->Parameters->Add( rootParam );
OleDbDataReader^ childNodesReader = childNodesCommand->ExecuteReader();
if ( childNodesReader->HasRows )
{
SiteMapNode ^ childNode = nullptr;
while ( childNodesReader->Read() )
{
childNode = gcnew SiteMapNode( this,
System::Convert::ToString(childNodesReader->GetInt32( 0 )),
childNodesReader->GetString( 1 ),
childNodesReader->GetString( 2 )
);
// Use the SiteMapNode AddNode method to add
// the SiteMapNode to the ChildNodes collection.
AddNode( childNode, rootNode );
}
}
childNodesReader->Close();
accessConnection->Close();
}
return rootNode;
}
finally
{
System::Threading::Monitor::Exit( this );
}
}
};
namespace Samples.AspNet.CS.Controls {
using System;
using System.Collections;
using System.Collections.Specialized;
using System.Data;
using System.Data.OleDb;
using System.Security.Permissions;
using System.Web;
/// An extremely simple AccessSiteMapProvider that only supports a
/// site map node hierarchy 1 level deep.
[AspNetHostingPermission(SecurityAction.Demand, Level=AspNetHostingPermissionLevel.Minimal)]
public class AccessSiteMapProvider : StaticSiteMapProvider
{
private SiteMapNode rootNode = null;
private OleDbConnection accessConnection = null;
// This string is case sensitive.
private string AccessConnectionStringName = "accessSiteMapConnectionString";
// Implement a default constructor.
public AccessSiteMapProvider () { }
// Some basic state to help track the initialization state of the provider.
private bool initialized = false;
public virtual bool IsInitialized {
get {
return initialized;
}
}
// Return the root node of the current site map.
public override SiteMapNode RootNode {
get {
SiteMapNode temp = null;
temp = BuildSiteMap();
return temp;
}
}
protected override SiteMapNode GetRootNodeCore() {
return RootNode;
}
// Initialize is used to initialize the properties and any state that the
// AccessProvider holds, but is not used to build the site map.
// The site map is built when the BuildSiteMap method is called.
public override void Initialize(string name, NameValueCollection attributes) {
if (IsInitialized)
return;
base.Initialize(name, attributes);
// Create and test the connection to the Microsoft Access database.
// Retrieve the Value of the Access connection string from the
// attributes NameValueCollection.
string connectionString = attributes[AccessConnectionStringName];
if (null == connectionString || connectionString.Length == 0)
throw new Exception ("The connection string was not found.");
else
accessConnection = new OleDbConnection(connectionString);
initialized = true;
}
///
/// SiteMapProvider and StaticSiteMapProvider methods that this derived class must override.
///
// Clean up any collections or other state that an instance of this may hold.
protected override void Clear() {
lock (this) {
rootNode = null;
base.Clear();
}
}
// Build an in-memory representation from persistent
// storage, and return the root node of the site map.
public override SiteMapNode BuildSiteMap() {
// Since the SiteMap class is static, make sure that it is
// not modified while the site map is built.
lock(this) {
// If there is no initialization, this method is being
// called out of order.
if (!IsInitialized) {
throw new Exception("BuildSiteMap called incorrectly.");
}
// If there is no root node, then there is no site map.
if (null == rootNode) {
// Start with a clean slate
Clear();
// Select the root node of the site map from Microsoft Access.
int rootNodeId = -1;
if (accessConnection.State == ConnectionState.Closed)
accessConnection.Open();
OleDbCommand rootNodeCommand =
new OleDbCommand("SELECT nodeid, url, name FROM SiteMap WHERE parentnodeid IS NULL",
accessConnection);
OleDbDataReader rootNodeReader = rootNodeCommand.ExecuteReader();
if(rootNodeReader.HasRows) {
rootNodeReader.Read();
rootNodeId = rootNodeReader.GetInt32(0);
// Create a SiteMapNode that references the current StaticSiteMapProvider.
rootNode = new SiteMapNode(this,
rootNodeId.ToString(),
rootNodeReader.GetString(1),
rootNodeReader.GetString(2));
}
else
{
return null;
}
rootNodeReader.Close();
// Select the child nodes of the root node.
OleDbCommand childNodesCommand =
new OleDbCommand("SELECT nodeid, url, name FROM SiteMap WHERE parentnodeid = ?",
accessConnection);
OleDbParameter rootParam = new OleDbParameter("parentid", OleDbType.Integer);
rootParam.Value = rootNodeId;
childNodesCommand.Parameters.Add(rootParam);
OleDbDataReader childNodesReader = childNodesCommand.ExecuteReader();
if (childNodesReader.HasRows) {
SiteMapNode childNode = null;
while(childNodesReader.Read()) {
childNode = new SiteMapNode(this,
childNodesReader.GetInt32(0).ToString(),
childNodesReader.GetString(1),
childNodesReader.GetString(2));
// Use the SiteMapNode AddNode method to add
// the SiteMapNode to the ChildNodes collection.
AddNode(childNode, rootNode);
}
}
childNodesReader.Close();
accessConnection.Close();
}
return rootNode;
}
}
}
}
Imports System.Collections
Imports System.Collections.Specialized
Imports System.Data
Imports System.Data.OleDb
Imports System.Security.Permissions
Imports System.Web
Namespace Samples.AspNet.VB.Controls
' An extremely simple AccessSiteMapProvider that only supports a
' site map node hierarchy one level deep.
<AspNetHostingPermission(SecurityAction.Demand, Level:=AspNetHostingPermissionLevel.Minimal)> _
Public Class AccessSiteMapProvider
Inherits StaticSiteMapProvider
Private aRootNode As SiteMapNode = Nothing
Private accessConnection As OleDbConnection = Nothing
' This string is case sensitive.
Private AccessConnectionStringName As String = "accessSiteMapConnectionString"
' Implement a default constructor.
Public Sub New()
End Sub
' Some basic state to help track the initialization state of the provider.
Private initialized As Boolean = False
Public Overridable ReadOnly Property IsInitialized() As Boolean
Get
Return initialized
End Get
End Property
' Return the root node of the current site map.
Public Overrides ReadOnly Property RootNode() As SiteMapNode
Get
Return BuildSiteMap()
End Get
End Property
Protected Overrides Function GetRootNodeCore() As SiteMapNode
Return RootNode
End Function
' Initialize is used to initialize the properties and any state that the
' AccessProvider holds, but is not used to build the site map.
' The site map is built when the BuildSiteMap method is called.
Public Overrides Sub Initialize(ByVal name As String, ByVal attributes As NameValueCollection)
If IsInitialized Then
Return
End If
MyBase.Initialize(name, attributes)
' Create and test the connection to the Microsoft Access database.
' Retrieve the Value of the Access connection string from the
' attributes NameValueCollection.
Dim connectionString As String = attributes(AccessConnectionStringName)
If Nothing = connectionString OrElse connectionString.Length = 0 Then
Throw New Exception("The connection string was not found.")
Else
accessConnection = New OleDbConnection(connectionString)
End If
initialized = True
End Sub
' SiteMapProvider and StaticSiteMapProvider methods that this derived class must override.
'
' Clean up any collections or other state that an instance of this may hold.
Protected Overrides Sub Clear()
SyncLock Me
aRootNode = Nothing
MyBase.Clear()
End SyncLock
End Sub
' Build an in-memory representation from persistent
' storage, and return the root node of the site map.
Public Overrides Function BuildSiteMap() As SiteMapNode
' Since the SiteMap class is static, make sure that it is
' not modified while the site map is built.
SyncLock Me
' If there is no initialization, this method is being
' called out of order.
If Not IsInitialized Then
Throw New Exception("BuildSiteMap called incorrectly.")
End If
' If there is no root node, then there is no site map.
If aRootNode Is Nothing Then
' Start with a clean slate
Clear()
' Select the root node of the site map from Microsoft Access.
Dim rootNodeId As Integer = -1
If accessConnection.State = ConnectionState.Closed Then
accessConnection.Open()
End If
Dim rootNodeCommand As New OleDbCommand("SELECT nodeid, url, name FROM SiteMap WHERE parentnodeid IS NULL", accessConnection)
Dim rootNodeReader As OleDbDataReader = rootNodeCommand.ExecuteReader()
If rootNodeReader.HasRows Then
rootNodeReader.Read()
rootNodeId = rootNodeReader.GetInt32(0)
' Create a SiteMapNode that references the current StaticSiteMapProvider.
aRootNode = New SiteMapNode(Me, rootNodeId.ToString(), rootNodeReader.GetString(1), rootNodeReader.GetString(2))
Else
Return Nothing
End If
rootNodeReader.Close()
' Select the child nodes of the root node.
Dim childNodesCommand As New OleDbCommand("SELECT nodeid, url, name FROM SiteMap WHERE parentnodeid = ?", accessConnection)
Dim rootParam As New OleDbParameter("parentid", OleDbType.Integer)
rootParam.Value = rootNodeId
childNodesCommand.Parameters.Add(rootParam)
Dim childNodesReader As OleDbDataReader = childNodesCommand.ExecuteReader()
If childNodesReader.HasRows Then
Dim childNode As SiteMapNode = Nothing
While childNodesReader.Read()
childNode = New SiteMapNode(Me, _
childNodesReader.GetInt32(0).ToString(), _
childNodesReader.GetString(1), _
childNodesReader.GetString(2))
' Use the SiteMapNode AddNode method to add
' the SiteMapNode to the ChildNodes collection.
AddNode(childNode, aRootNode)
End While
End If
childNodesReader.Close()
accessConnection.Close()
End If
Return aRootNode
End SyncLock
End Function 'BuildSiteMap
End Class
End Namespace
最后, 在 AccessSiteMapProvider
以下 Web.config 文件中将 配置为默认提供程序。
<configuration>
<system.web>
<siteMap defaultProvider="AccessSiteMapProvider">
<providers>
<add
name="AccessSiteMapProvider"
type="Samples.AspNet.AccessSiteMapProvider,Samples.AspNet "
accessSiteMapConnectionString="PROVIDER=MICROSOFT.JET.OLEDB.4.0;DATA SOURCE=sitemap.mdb "/>
</providers>
</siteMap>
</system.web>
</configuration>
注解
类 StaticSiteMapProvider 是抽象 SiteMapProvider 类的部分实现,并提供两个附加方法: AddNode 和 RemoveNode,以及抽象 BuildSiteMap 和受保护的 Clear 方法。
类 StaticSiteMapProvider 支持编写站点地图提供程序 (例如, XmlSiteMapProvider) 将存储在永久性存储中的站点地图转换为存储在内存中的站点地图。 类 StaticSiteMapProvider 提供用于存储和检索 SiteMapNode 对象的基本实现。
SiteMapProvider和 StaticSiteMapProvider 类支持站点地图提供程序层次结构的概念,其中站点地图提供程序可以与其他站点地图提供程序具有分层关系。 此模式是使用 和 ParentProvider 属性实现的RootProvider。
类 StaticSiteMapProvider 将其 SiteMapNode 对象存储在哈希表中,并在内部使用 SiteMapNode.Url 页面的 属性(由站点地图节点表示)作为键。 (如果站点地图节点未指定 URL,则使用自动生成的唯一密钥对其进行跟踪。) 因此,不能有站点地图节点,其中具有相同 URL 的站点地图节点多次使用。 例如,尝试使用 XmlSiteMapProvider 类(默认 ASP.NET 站点地图提供程序)加载以下代码示例中所示的站点地图节点,或者从 StaticSiteMapProvider 类派生的任何站点地图提供程序都不起作用,因为多次使用AboutUs.aspx页面。
<sitemap>
<sitemapnode title="Home" description="Home" url="default.aspx" >
<sitemapnode title="Catalog" description="Our catalog" url="catalog.aspx"/>
<sitemapnode title="About Us" description="All about our company" url="aboutus.aspx"/>
<sitemapnode title="Driving Directions" description="Directions to our store" url="aboutus.aspx"/>
</sitemapnode>
</sitemap>
如果要扩展 StaticSiteMapProvider 类,则最重要的三种方法是 GetRootNodeCore、 Initialize和 BuildSiteMap 方法。 Clear和 FindSiteMapNode 方法的默认实现足以满足大多数自定义站点地图提供程序实现的需求。
调用 Initialize 方法可初始化派生的站点地图提供程序,包括加载站点地图数据所需的任何资源,但它确实尝试在内存中生成站点地图节点。 如果派生类使用文件来存储站点地图数据,则可以在此处执行任何文件初始化。 如果站点地图节点使用某种其他类型的数据存储(例如关系数据库),则可以在此处执行连接初始化。 其他属性(如文件名或连接字符串)放置在配置中的站点地图提供程序元素上,由 ASP.NET 配置系统进行处理,并使用 参数传递给 Initialize 方法 attributes
。
方法 BuildSiteMap 必须由派生自 StaticSiteMapProvider 类的所有类重写,并调用 该方法以从永久性存储加载站点地图节点并将其转换为内部表示形式。 方法BuildSiteMap在 和 XmlSiteMapProvider 类的许多默认成员实现StaticSiteMapProvider中以内部方式调用。 如果实现自己的站点地图提供程序,请确保站点地图数据处理一次,如果已加载站点地图信息,则立即返回对 BuildSiteMap 方法的后续调用。 实现 BuildSiteMap 方法时,请确保其线程安全,因为多个并发页面请求可能会间接导致多次调用来加载站点地图信息。 站点地图基础结构支持根据用户的角色显示站点地图信息。 根据 Roles 各个 SiteMapNode 对象支持的属性,不同的用户可能具有不同的导航结构。 类的站点地图节点检索成员 StaticSiteMapProvider 的默认实现通过调用 IsAccessibleToUser 方法自动执行安全修整。
AddNode和 ClearRemoveNode 方法以线程安全的方式操作用于跟踪站点地图节点的内部集合。
实施者说明
从 StaticSiteMapProvider 类继承时,必须重写以下成员: BuildSiteMap()。
构造函数
StaticSiteMapProvider() |
初始化 StaticSiteMapProvider 类的新实例。 |
属性
CurrentNode |
获取表示当前请求页的 SiteMapNode 对象。 (继承自 SiteMapProvider) |
Description |
获取一条简短的易懂描述,它适合在管理工具或其他用户界面 (UI) 中显示。 (继承自 ProviderBase) |
EnableLocalization |
获取或设置一个布尔值,该值指示是否返回 SiteMapNode 特性的本地化的值。 (继承自 SiteMapProvider) |
Name |
获得一个友好名称,用于在配置过程中引用提供程序。 (继承自 ProviderBase) |
ParentProvider |
获取或设置当前提供程序的父 SiteMapProvider 对象。 (继承自 SiteMapProvider) |
ResourceKey |
获取或设置用于本地化 SiteMapNode 特性的资源键。 (继承自 SiteMapProvider) |
RootNode |
获取当前提供程序表示的站点地图数据的根 SiteMapNode 对象。 (继承自 SiteMapProvider) |
RootProvider |
获取当前提供程序层次结构中的根 SiteMapProvider 对象。 (继承自 SiteMapProvider) |
SecurityTrimmingEnabled |
获取一个布尔值,该值指示站点地图提供程序是否根据用户的角色筛选站点地图节点。 (继承自 SiteMapProvider) |
方法
事件
SiteMapResolve |
当调用 CurrentNode 属性时发生。 (继承自 SiteMapProvider) |