自定义SiteMapProvider实现从SQL Server中读取站点地图数据结构收藏【转载】
转载自: http://blog.csdn.net/zwyl2001/archive/2007/07/29/1715267.aspx
关键的几个地方
1. 数据库结构
NodeId varchar(10)
NodeName varchar(20)
NodeIcon varchar(20)
NodeUrl varchar(50)
NodeDescrition varchar(256)
ParentNodeId varchar(10)
2. 创建自定义Provider
public class SqlSiteMapProvider:StaticSiteMapProvider
{
Microsoft.Practices.EnterpriseLibrary.Data.Database _Database;
private bool _Initialized = false;
/// <summary>
/// 站点地图根节点
/// </summary>
private SiteMapNode _RootNode = null;
/// <summary>
/// 清除站点地图中的节点。
/// </summary>
protected override void Clear()
{
lock (this)
{
_RootNode = null;
base.Clear();
}
}
/// <summary>
/// 从数据库中检索站点数据并构建站点地图
/// </summary>
/// <returns></returns>
public override SiteMapNode BuildSiteMap()
{
//因为SiteMap类是静态的,所以应确保站点地图被构建完成之前,他不要被修改。
lock (this)
{
//如果提供程序没有被初始化,抛出异常。
if (!IsInitialized)
{
throw new ProviderException("BuildSiteMap called incorrectly.");
}
if (_RootNode == null)
{
//清空节点
Clear();
// 构造根节点
string rootNodeId = "";
//TODO:具体程序中修改之
DbDataReader rootNodeReader = _Database.ExecuteReader(CommandType.Text, "SELECT nodeid, nodeurl, nodename,nodeicon FROM SiteMap WHERE ParentNodeId IS NULL") as DbDataReader;
try
{
if (rootNodeReader.HasRows)
{
rootNodeReader.Read();
rootNodeId = rootNodeReader.GetString(0);
// 为当前的 StaticSiteMapProvider创建一个 SiteMapNode 根节点 .
_RootNode = new SiteMapNode(this,
rootNodeId,
rootNodeReader.GetString(1),
rootNodeReader.GetString(2));
}
else
{
return null;
}
}
finally
{
rootNodeReader.Close();
}
// 构造子节点
//TODO:具体程序中修改之
System.Data.Common.DbCommand command = _Database.GetSqlStringCommand("SELECT nodeid, nodeurl, nodename,nodeicon FROM SiteMap WHERE ParentNodeId = @nodeid");
_Database.AddInParameter(command,"@nodeid", DbType.String,rootNodeId);
DbDataReader childNodesReader = _Database.ExecuteReader(command) as DbDataReader;
try
{
if (childNodesReader.HasRows)
{
SiteMapNode childNode = null;
while (childNodesReader.Read())
{
childNode = new SiteMapNode(this,
childNodesReader.GetString(0),
childNodesReader.GetString(1),
childNodesReader.GetString(2));
//将图标信息添加到节点的自定义属性中。
childNode["Icon"] = childNodesReader.GetString(3);
//向根节点中添加子节点。
AddNode(childNode, _RootNode);
}
}
}
finally
{
childNodesReader.Close();
}
}
//返回构建后的根节点。
return _RootNode;
}
}
/// <summary>
/// 获得已经构建完成的根节点。
/// </summary>
/// <returns>SiteMap根节点</returns>
protected override SiteMapNode GetRootNodeCore()
{
return RootNode;
}
/// <summary>
/// 获取当前提供程序是否已经被初始化。
/// </summary>
public virtual bool IsInitialized
{
get
{
return _Initialized;
}
}
/// <summary>
/// 获取SiteMap根节点
/// </summary>
public override SiteMapNode RootNode
{
get
{
SiteMapNode temp = null;
temp = BuildSiteMap();
return temp;
}
}
/// <summary>
/// 初始化提供程序。
/// </summary>
/// <param name="name">提供程序的名称</param>
/// <param name="config">配置参数</param>
public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
{
if (config == null)
{
throw new ArgumentNullException("config");
}
if (string.IsNullOrEmpty(name))
{
name = "AspNetSqlSiteMapProvider";
}
if (string.IsNullOrEmpty(config["description"]))
{
config.Remove("description");
config.Add("description", "SiteMapSqlProvider_description");
}
base.Initialize(name, config);
string specifiedConnectionString = config["connectionStringName"];
if ((specifiedConnectionString == null) || (specifiedConnectionString.Length < 1))
{
throw new ProviderException("Connection_name_not_specified");
}
_Database = Microsoft.Practices.EnterpriseLibrary.Data.DatabaseFactory.CreateDatabase(specifiedConnectionString);
_Initialized = true;
}
}
3. 配置文件修改
<siteMap defaultProvider="SqlSiteMapProvider">
<providers>
<add name="SqlSiteMapProvider"
type="SqlSiteMapProvider"
connectionStringName="LocalServer"/>
</providers>
</siteMap>
4. 还可以把动态部分嵌入到固定的Web.Sitemap文件中
<?xml version="1.0" encoding="utf-8" ?>
<siteMap>
<siteMapNode title="程序菜单" url="" description="">
<siteMapNode title="系统配置" url="" description="">
<siteMapNode provider="SqlSiteMapProvider"/>
</siteMapNode>
</siteMapNode>
</siteMap>
5. 站点地图项目可以跟角色进行绑定。
通过siteMapNode元素的Roles属性指定