ASP.NET 2.0 中的站点导航提供程序向应用程序中的页公开导航信息,使您可以独立于页的实际物理布局定义站点的结构。默认站点导航提供程序基于XML,但通过为站点地图编写自定义提供程序,也可以从任意后端公开此信息。
关键
1、创建.sitemap文件,其实就是一个xml文件,包括有着层次结构的
2、
Url - 链接地址
Title - 显示的标题
Description - 描述(ToolTip)
resourceKey - 本地化用的(要在
securityTrimmingEnabled - 是否让sitemap支持安全特性
roles - 哪些角色可以访问当前节点,多角色用逗号隔开(需要将securityTrimmingEnabled设置为true)
siteMapFile - 引用另一个sitemap文件
注:应用权限的时候,Web.config中要有相对应的配置
3、可以通过SiteMap和SiteMapNode类访问站点地图数据
4、自定义站点地图提供程序应该写一个继承自StaticSiteMapProvider的类
5、XmlSiteMapProvider要求站点地图节点具有唯一的URL
示例
SiteMap/Web.sitemap(包括一个有siteMapFile属性的节点)
xml version="1.0" encoding="utf-8"
?>
< siteMap xmlns ="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
< siteMapNode url ="~/SiteMap/Test.aspx#1" title ="首页" description ="首页描述" >
< siteMapNode url ="~/SiteMap/Test.aspx#2" title ="频道1" description ="频道1描述" />
< siteMapNode url ="~/SiteMap/Test.aspx#3" title ="频道2" description ="频道2描述" />
< siteMapNode siteMapFile ="WebChild.sitemap" >
siteMapNode >
< siteMapNode url ="~/SiteMap/Test.aspx#4" title ="频道4" description ="频道4描述" />
siteMapNode >
siteMap >
< siteMap xmlns ="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
< siteMapNode url ="~/SiteMap/Test.aspx#1" title ="首页" description ="首页描述" >
< siteMapNode url ="~/SiteMap/Test.aspx#2" title ="频道1" description ="频道1描述" />
< siteMapNode url ="~/SiteMap/Test.aspx#3" title ="频道2" description ="频道2描述" />
< siteMapNode siteMapFile ="WebChild.sitemap" >
siteMapNode >
< siteMapNode url ="~/SiteMap/Test.aspx#4" title ="频道4" description ="频道4描述" />
siteMapNode >
siteMap >
SiteMap/WebChild.sitemap(上面.sitemap文件某个节点的siteMapFile属性所指定的文件)
xml version="1.0" encoding="utf-8"
?>
< siteMap xmlns ="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
< siteMapNode url ="~/SiteMap/Test.aspx#5" title ="频道3" description ="频道3" >
< siteMapNode url ="~/SiteMap/Test.aspx#6" title ="栏目1" description ="栏目1描述" />
< siteMapNode url ="~/SiteMap/Test.aspx#7" title ="栏目2" description ="栏目2描述" />
< siteMapNode url ="~/SiteMap/Test.aspx#8" title ="栏目3" description ="栏目3描述" />
siteMapNode >
siteMap >
< siteMap xmlns ="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
< siteMapNode url ="~/SiteMap/Test.aspx#5" title ="频道3" description ="频道3" >
< siteMapNode url ="~/SiteMap/Test.aspx#6" title ="栏目1" description ="栏目1描述" />
< siteMapNode url ="~/SiteMap/Test.aspx#7" title ="栏目2" description ="栏目2描述" />
< siteMapNode url ="~/SiteMap/Test.aspx#8" title ="栏目3" description ="栏目3描述" />
siteMapNode >
siteMap >
站点地图测试
SiteMap/Test.aspx
<%
@ Page Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true" CodeFile="Test.aspx.cs"
Inherits="SiteMap_Test" Title="站点地图测试" %>
< asp:Content ID ="Content1" ContentPlaceHolderID ="ContentPlaceHolder1" runat ="Server" >
< p >
< asp:TreeView ID ="TreeView1" runat ="server" DataSourceID ="SiteMapDataSource1" >
asp:TreeView >
< asp:Menu ID ="Menu1" runat ="server" DataSourceID ="SiteMapDataSource2" Orientation ="Horizontal" >
asp:Menu >
<% --显示根节点的数据源-- %>
< asp:SiteMapDataSource ID ="SiteMapDataSource1" runat ="server" SiteMapProvider ="XmlSiteMapProviderTest" />
<% --不显示根节点的数据源-- %>
< asp:SiteMapDataSource ID ="SiteMapDataSource2" runat ="server" SiteMapProvider ="XmlSiteMapProviderTest"
ShowStartingNode ="false" />
p >
< p >
编码方式访问节点信息如下 < br />
< asp:Label ID ="lbl" runat ="server" BackColor ="#DDDDDD" />
p >
asp:Content >
Inherits="SiteMap_Test" Title="站点地图测试" %>
< asp:Content ID ="Content1" ContentPlaceHolderID ="ContentPlaceHolder1" runat ="Server" >
< p >
< asp:TreeView ID ="TreeView1" runat ="server" DataSourceID ="SiteMapDataSource1" >
asp:TreeView >
< asp:Menu ID ="Menu1" runat ="server" DataSourceID ="SiteMapDataSource2" Orientation ="Horizontal" >
asp:Menu >
<% --显示根节点的数据源-- %>
< asp:SiteMapDataSource ID ="SiteMapDataSource1" runat ="server" SiteMapProvider ="XmlSiteMapProviderTest" />
<% --不显示根节点的数据源-- %>
< asp:SiteMapDataSource ID ="SiteMapDataSource2" runat ="server" SiteMapProvider ="XmlSiteMapProviderTest"
ShowStartingNode ="false" />
p >
< p >
编码方式访问节点信息如下 < br />
< asp:Label ID ="lbl" runat ="server" BackColor ="#DDDDDD" />
p >
asp:Content >
SiteMap/Test.aspx.cs
using
System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
public partial class SiteMap_Test : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
// 获取当前节点的Title
lbl.Text = "当前节点标题:" + SiteMap.CurrentNode.Title + "
";
// 取得url为“~/Default.aspx”的SiteMapNode
SiteMapNode smn = SiteMap.Provider.FindSiteMapNode("~/Default.aspx");
lbl.Text += "Default.aspx节点的Url:" + smn.Url;
}
}
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
public partial class SiteMap_Test : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
// 获取当前节点的Title
lbl.Text = "当前节点标题:" + SiteMap.CurrentNode.Title + "
";
// 取得url为“~/Default.aspx”的SiteMapNode
SiteMapNode smn = SiteMap.Provider.FindSiteMapNode("~/Default.aspx");
lbl.Text += "Default.aspx节点的Url:" + smn.Url;
}
}
站点地图测试(从数据库读数据)
SiteMap/FromDatabase.aspx
<%
@ Page Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true" CodeFile="FromDatabase.aspx.cs"
Inherits="SiteMap_FromDatabase" Title="站点地图测试(从数据库读数据)" %>
< asp:Content ID ="Content1" ContentPlaceHolderID ="ContentPlaceHolder1" runat ="Server" >
< asp:TreeView ID ="TreeView1" runat ="server" DataSourceID ="SiteMapDataSource1" >
asp:TreeView >
< asp:SiteMapDataSource ID ="SiteMapDataSource1" runat ="server" SiteMapProvider ="SqlSiteMapProvider" />
asp:Content >
Inherits="SiteMap_FromDatabase" Title="站点地图测试(从数据库读数据)" %>
< asp:Content ID ="Content1" ContentPlaceHolderID ="ContentPlaceHolder1" runat ="Server" >
< asp:TreeView ID ="TreeView1" runat ="server" DataSourceID ="SiteMapDataSource1" >
asp:TreeView >
< asp:SiteMapDataSource ID ="SiteMapDataSource1" runat ="server" SiteMapProvider ="SqlSiteMapProvider" />
asp:Content >
自定义站点地图提供程序(SqlServer方式)
SqlSiteMapProvider.cs(“sp_GetSiteMap”为读取站点地图数据的存储过程,详见源码)
using
System;
using System.Web;
using System.Data.SqlClient;
using System.Collections.Specialized;
using System.Configuration;
using System.Web.Configuration;
using System.Collections.Generic;
using System.Configuration.Provider;
using System.Security.Permissions;
using System.Data.Common;
using System.Data;
/**/ ///
/// SqlSiteMapProvider
///
public class SqlSiteMapProvider : StaticSiteMapProvider
{
private string _strCon;
private int _indexID, _indexTitle, _indexUrl, _indexDesc, _indexParent;
// 节点
private SiteMapNode _node;
// 节点字典表
private Dictionary<int, SiteMapNode> _nodes = new Dictionary<int, SiteMapNode>();
// 用于单例模式
private readonly object _lock = new object();
/**////
/// 初始化
///
/// name
/// config
public override void Initialize(string name, NameValueCollection config)
{
// 验证是否有config
if (config == null)
throw new ArgumentNullException("config不能是null");
// 没有provider则设置为默认的
if (String.IsNullOrEmpty(name))
name = "SqlSiteMapProvider";
// 没有描述就增加一个描述
if (string.IsNullOrEmpty(config["description"]))
{
config.Remove("description");
config.Add("description", "SqlSiteMapProvider");
}
// 调用基类的初始化方法
base.Initialize(name, config);
// 初始化连接字符串
string conStringName = config["connectionStringName"];
if (String.IsNullOrEmpty(conStringName))
throw new ProviderException("没找到connectionStringName");
config.Remove("connectionStringName");
if (WebConfigurationManager.ConnectionStrings[conStringName] == null)
throw new ProviderException("根据connectionStringName没找到连接字符串");
// 获得连接字符串
_strCon = WebConfigurationManager.ConnectionStrings[conStringName].ConnectionString;
if (String.IsNullOrEmpty(_strCon))
throw new ProviderException("连接字符串是空的");
}
/**////
/// 从持久性存储区加载站点地图信息,并在内存中构建它
///
///
public override SiteMapNode BuildSiteMap()
{
lock (_lock)
{
// 单例模式的实现
if (_node != null)
return _node;
SqlConnection connection = new SqlConnection(_strCon);
try
{
SqlCommand command = new SqlCommand("sp_GetSiteMap", connection);
command.CommandType = CommandType.StoredProcedure;
connection.Open();
SqlDataReader reader = command.ExecuteReader();
// 获得各个字段的索引
_indexID = reader.GetOrdinal("ID");
_indexUrl = reader.GetOrdinal("Url");
_indexTitle = reader.GetOrdinal("Title");
_indexDesc = reader.GetOrdinal("Description");
_indexParent = reader.GetOrdinal("Parent");
if (reader.Read())
{
// 把第一条记录作为根节点添加
_node = CreateSiteMapNodeFromDataReader(reader);
AddNode(_node, null);
// 构造节点树
while (reader.Read())
{
// 在站点地图中增加一个节点
SiteMapNode node = CreateSiteMapNodeFromDataReader(reader);
AddNode(node, GetParentNodeFromDataReader(reader));
}
}
reader.Close();
}
catch (Exception ex)
{
throw new Exception(ex.ToString());
}
finally
{
connection.Close();
}
// 返回SiteMapNode
return _node;
}
}
/**////
/// 将检索目前由当前提供程序管理的所有节点的根节点
///
///
protected override SiteMapNode GetRootNodeCore()
{
lock (_lock)
{
return BuildSiteMap();
}
}
/**////
/// 根据DataReader读出来的数据返回SiteMapNode
///
/// DbDataReader
///
private SiteMapNode CreateSiteMapNodeFromDataReader(DbDataReader reader)
{
if (reader.IsDBNull(_indexID))
throw new ProviderException("没找到ID");
int id = reader.GetInt32(_indexID);
if (_nodes.ContainsKey(id))
throw new ProviderException("不能有重复ID");
// 根据字段索引获得相应字段的值
string title = reader.IsDBNull(_indexTitle) ? null : reader.GetString(_indexTitle).Trim();
string url = reader.IsDBNull(_indexUrl) ? null : reader.GetString(_indexUrl).Trim();
string description = reader.IsDBNull(_indexDesc) ? null : reader.GetString(_indexDesc).Trim();
// 新建一个SiteMapNode
SiteMapNode node = new SiteMapNode(this, id.ToString(), url, title, description);
// 把这个SiteMapNode添加进节点字典表里
_nodes.Add(id, node);
// 返回这个SiteMapNode
return node;
}
/**////
/// 得到父节点的SiteMapNode
///
///
///
private SiteMapNode GetParentNodeFromDataReader(DbDataReader reader)
{
if (reader.IsDBNull(_indexParent))
throw new ProviderException("父节点不能是空");
int pid = reader.GetInt32(_indexParent);
if (!_nodes.ContainsKey(pid))
throw new ProviderException("有重复节点ID");
// 返回父节点的SiteMapNode
return _nodes[pid];
}
}
using System.Web;
using System.Data.SqlClient;
using System.Collections.Specialized;
using System.Configuration;
using System.Web.Configuration;
using System.Collections.Generic;
using System.Configuration.Provider;
using System.Security.Permissions;
using System.Data.Common;
using System.Data;
/**/ ///
/// SqlSiteMapProvider
///
public class SqlSiteMapProvider : StaticSiteMapProvider
{
private string _strCon;
private int _indexID, _indexTitle, _indexUrl, _indexDesc, _indexParent;
// 节点
private SiteMapNode _node;
// 节点字典表
private Dictionary<int, SiteMapNode> _nodes = new Dictionary<int, SiteMapNode>();
// 用于单例模式
private readonly object _lock = new object();
/**////
/// 初始化
///
/// name
/// config
public override void Initialize(string name, NameValueCollection config)
{
// 验证是否有config
if (config == null)
throw new ArgumentNullException("config不能是null");
// 没有provider则设置为默认的
if (String.IsNullOrEmpty(name))
name = "SqlSiteMapProvider";
// 没有描述就增加一个描述
if (string.IsNullOrEmpty(config["description"]))
{
config.Remove("description");
config.Add("description", "SqlSiteMapProvider");
}
// 调用基类的初始化方法
base.Initialize(name, config);
// 初始化连接字符串
string conStringName = config["connectionStringName"];
if (String.IsNullOrEmpty(conStringName))
throw new ProviderException("没找到connectionStringName");
config.Remove("connectionStringName");
if (WebConfigurationManager.ConnectionStrings[conStringName] == null)
throw new ProviderException("根据connectionStringName没找到连接字符串");
// 获得连接字符串
_strCon = WebConfigurationManager.ConnectionStrings[conStringName].ConnectionString;
if (String.IsNullOrEmpty(_strCon))
throw new ProviderException("连接字符串是空的");
}
/**////
/// 从持久性存储区加载站点地图信息,并在内存中构建它
///
///
public override SiteMapNode BuildSiteMap()
{
lock (_lock)
{
// 单例模式的实现
if (_node != null)
return _node;
SqlConnection connection = new SqlConnection(_strCon);
try
{
SqlCommand command = new SqlCommand("sp_GetSiteMap", connection);
command.CommandType = CommandType.StoredProcedure;
connection.Open();
SqlDataReader reader = command.ExecuteReader();
// 获得各个字段的索引
_indexID = reader.GetOrdinal("ID");
_indexUrl = reader.GetOrdinal("Url");
_indexTitle = reader.GetOrdinal("Title");
_indexDesc = reader.GetOrdinal("Description");
_indexParent = reader.GetOrdinal("Parent");
if (reader.Read())
{
// 把第一条记录作为根节点添加
_node = CreateSiteMapNodeFromDataReader(reader);
AddNode(_node, null);
// 构造节点树
while (reader.Read())
{
// 在站点地图中增加一个节点
SiteMapNode node = CreateSiteMapNodeFromDataReader(reader);
AddNode(node, GetParentNodeFromDataReader(reader));
}
}
reader.Close();
}
catch (Exception ex)
{
throw new Exception(ex.ToString());
}
finally
{
connection.Close();
}
// 返回SiteMapNode
return _node;
}
}
/**////
/// 将检索目前由当前提供程序管理的所有节点的根节点
///
///
protected override SiteMapNode GetRootNodeCore()
{
lock (_lock)
{
return BuildSiteMap();
}
}
/**////
/// 根据DataReader读出来的数据返回SiteMapNode
///
/// DbDataReader
///
private SiteMapNode CreateSiteMapNodeFromDataReader(DbDataReader reader)
{
if (reader.IsDBNull(_indexID))
throw new ProviderException("没找到ID");
int id = reader.GetInt32(_indexID);
if (_nodes.ContainsKey(id))
throw new ProviderException("不能有重复ID");
// 根据字段索引获得相应字段的值
string title = reader.IsDBNull(_indexTitle) ? null : reader.GetString(_indexTitle).Trim();
string url = reader.IsDBNull(_indexUrl) ? null : reader.GetString(_indexUrl).Trim();
string description = reader.IsDBNull(_indexDesc) ? null : reader.GetString(_indexDesc).Trim();
// 新建一个SiteMapNode
SiteMapNode node = new SiteMapNode(this, id.ToString(), url, title, description);
// 把这个SiteMapNode添加进节点字典表里
_nodes.Add(id, node);
// 返回这个SiteMapNode
return node;
}
/**////
/// 得到父节点的SiteMapNode
///
///
///
private SiteMapNode GetParentNodeFromDataReader(DbDataReader reader)
{
if (reader.IsDBNull(_indexParent))
throw new ProviderException("父节点不能是空");
int pid = reader.GetInt32(_indexParent);
if (!_nodes.ContainsKey(pid))
throw new ProviderException("有重复节点ID");
// 返回父节点的SiteMapNode
return _nodes[pid];
}
}
上面两个测试页面所需的web.config中的配置
<
configuration
>
< appSettings />
< connectionStrings >
< add name ="SqlConnectionString" connectionString ="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\Database.mdf;Integrated Security=True;User Instance=True" />
connectionStrings >
< system .web >
< siteMap enabled ="true" defaultProvider ="XmlSiteMapProvider" >
< providers >
< add name ="XmlSiteMapProvider" type ="System.Web.XmlSiteMapProvider, System.Web, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" siteMapFile ="~/Web.sitemap" />
< add name ="XmlSiteMapProviderTest" type ="System.Web.XmlSiteMapProvider, System.Web, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" siteMapFile ="~/Sitemap/Web.sitemap" />
< add name ="SqlSiteMapProvider" type ="SqlSiteMapProvider" connectionStringName ="SqlConnectionString" />
providers >
siteMap >
system.web >
configuration >
< appSettings />
< connectionStrings >
< add name ="SqlConnectionString" connectionString ="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\Database.mdf;Integrated Security=True;User Instance=True" />
connectionStrings >
< system .web >
< siteMap enabled ="true" defaultProvider ="XmlSiteMapProvider" >
< providers >
< add name ="XmlSiteMapProvider" type ="System.Web.XmlSiteMapProvider, System.Web, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" siteMapFile ="~/Web.sitemap" />
< add name ="XmlSiteMapProviderTest" type ="System.Web.XmlSiteMapProvider, System.Web, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" siteMapFile ="~/Sitemap/Web.sitemap" />
< add name ="SqlSiteMapProvider" type ="SqlSiteMapProvider" connectionStringName ="SqlConnectionString" />
providers >
siteMap >
system.web >
configuration >
OK
[源码下载]