SiteMapPath使用

来源:互联网 发布:tomcat启动查看端口号 编辑:程序博客网 时间:2024/05/28 15:54

转贴自  http://www.cnblogs.com/zijinguang/articles/1226098.html

 

SiteMapPath是ASP.NET 2.0 版包含导航控件中的一种,其它还包括 Menu 控件和TreeView 控件,这些控件使导航菜单的创建、自定义和维护变得很容易导航控件的一种。今天有朋友问我用没有过SiteMapPath 于是从网上找到一个不错的例子转载下,给可能用到此控件的朋友一个帮助。高手现在就可以离开了。


1、创建.sitemap文件,其实就是一个xml文件,包括有着层次结构的<siteMapNode>元素

2、<siteMapNode>元素的属性:
  Url - 链接地址
  Title - 显示的标题
  Description - 描述(ToolTip)
  resourceKey - 本地化用的(要在<siteMap>节点加上这个属性enableLocalization=true)   
  securityTrimmingEnabled - 是否让sitemap支持安全特性
  roles - 哪些角色可以访问当前节点,多角色用逗号隔开(需要将securityTrimmingEnabled设置为true)
  siteMapFile - 引用另一个sitemap文件
  注:应用权限的时候,Web.config中的SiteMap节点的Provider也要有相对应的配置(securityTrimmingEnabled="true"

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/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/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>


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 + "<br />";

        
// 取得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>


自定义站点地图提供程序(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;

/// <summary>
/// SqlSiteMapProvider
/// </summary>

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();

    
/// <summary>
    
/// 初始化
    
/// </summary>
    
/// <param name="name">name</param>
    
/// <param name="config">config</param>

    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("连接字符串是空的");
    }


    
/// <summary>
    
/// 从持久性存储区加载站点地图信息,并在内存中构建它
    
/// </summary>
    
/// <returns></returns>

    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;
        }

    }


    
/// <summary>
    
/// 将检索目前由当前提供程序管理的所有节点的根节点
    
/// </summary>
    
/// <returns></returns>

    protected override SiteMapNode GetRootNodeCore()
    
{
        
lock (_lock)
        
{
            
return BuildSiteMap();
        }

    }


    
/// <summary>
    
/// 根据DataReader读出来的数据返回SiteMapNode
    
/// </summary>
    
/// <param name="reader">DbDataReader</param>
    
/// <returns></returns>

    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;
    }


    
/// <summary>
    
/// 得到父节点的SiteMapNode
    
/// </summary>
    
/// <param name="reader"></param>
    
/// <returns></returns>

    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>

文章作者 webabcd 原文地址 http://www.cnblogs.com/webabcd/archive/2007/02/14/650773.html
以下是微软的代码:

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;
using System.Web.Caching;

/// <summary>
/// Summary description for SqlSiteMapProvider
/// </summary>

[SqlClientPermission (SecurityAction.Demand, Unrestricted=true)]
public class SqlSiteMapProvider : StaticSiteMapProvider
{
    
private const string _errmsg1 = "Missing node ID";
    
private const string _errmsg2 = "Duplicate node ID";
    
private const string _errmsg3 = "Missing parent ID";
    
private const string _errmsg4 = "Invalid parent ID";
    
private const string _errmsg5 = "Empty or missing connectionStringName";
    
private const string _errmsg6 = "Missing connection string";
    
private const string _errmsg7 = "Empty connection string";
    
private const string _errmsg8 = "Invalid sqlCacheDependency";
    
private const string _cacheDependencyName = "__SiteMapCacheDependency";

    
private string _connect;              // Database connection string
    private string _database, _table;     // Database info for SQL Server 7/2000 cache dependency
    private bool _2005dependency = false// Database info for SQL Server 2005 cache dependency
    private int _indexID, _indexTitle, _indexUrl, _indexDesc, _indexRoles, _indexParent;
    
private Dictionary<int, SiteMapNode> _nodes = new Dictionary<int, SiteMapNode>(16);
    
private readonly object _lock = new object();
    
private SiteMapNode _root;

    
public override void Initialize (string name, NameValueCollection config)
    
{
        
// Verify that config isn't null
        if (config == null)
            
throw new ArgumentNullException("config");

        
// Assign the provider a default name if it doesn't have one
        if (String.IsNullOrEmpty(name))
            name 
= "SqlSiteMapProvider";

        
// Add a default "description" attribute to config if the
        
// attribute doesn锟絫 exist or is empty
        if (string.IsNullOrEmpty(config["description"]))
        
{
            config.Remove(
"description");
            config.Add(
"description""SQL site map provider");
        }


        
// Call the base class's Initialize method
        base.Initialize(name, config);

        
// Initialize _connect
        string connect = config["connectionStringName"];

        
if (String.IsNullOrEmpty(connect))
            
throw new ProviderException(_errmsg5);

        config.Remove(
"connectionStringName");

        
if (WebConfigurationManager.ConnectionStrings[connect] == null)
            
throw new ProviderException(_errmsg6);

        _connect 
= WebConfigurationManager.ConnectionStrings[connect].ConnectionString;

        
if (String.IsNullOrEmpty(_connect))
            
throw new ProviderException(_errmsg7);
        
        
// Initialize SQL cache dependency info
        string dependency = config["sqlCacheDependency"];

        
if (!String.IsNullOrEmpty(dependency))
        
{
            
if (String.Equals(dependency, "CommandNotification", StringComparison.InvariantCultureIgnoreCase))
            
{
                SqlDependency.Start(_connect);
                _2005dependency 
= true;
            }

            
else
            
{
                
// If not "CommandNotification", then extract database and table names
                string[] info = dependency.Split(new char[] ':' });
                
if (info.Length != 2)
                    
throw new ProviderException(_errmsg8);

                _database 
= info[0];
                _table 
= info[1];
            }


            config.Remove(
"sqlCacheDependency");
        }

        
        
// SiteMapProvider processes the securityTrimmingEnabled
        
// attribute but fails to remove it. Remove it now so we can
        
// check for unrecognized configuration attributes.

        
if (config["securityTrimmingEnabled"!= null)
            config.Remove(
"securityTrimmingEnabled");
        
        
// Throw an exception if unrecognized attributes remain
        if (config.Count > 0)
        
{
            
string attr = config.GetKey(0);
            
if (!String.IsNullOrEmpty(attr))
                
throw new ProviderException("Unrecognized attribute: " + attr);
        }

    }


    
public override SiteMapNode BuildSiteMap()
    
{
        
lock (_lock)
        
{
            
// Return immediately if this method has been called before
            if (_root != null)
                
return _root;

            
// Query the database for site map nodes
            SqlConnection connection = new SqlConnection(_connect);

            
try
            
{
                SqlCommand command 
= new SqlCommand("proc_GetSiteMap", connection);
                command.CommandType 
= CommandType.StoredProcedure;

                
// Create a SQL cache dependency if requested
                SqlCacheDependency dependency = null;

                
if (_2005dependency)
                    dependency 
= new SqlCacheDependency(command);
                
else if (!String.IsNullOrEmpty(_database) && !string.IsNullOrEmpty(_table))
                    dependency 
= new SqlCacheDependency(_database, _table);

                connection.Open();
                SqlDataReader reader 
= 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");

                
if (reader.Read())
                
{
                    
// Create the root SiteMapNode and add it to the site map
                    _root = CreateSiteMapNodeFromDataReader(reader);
                    AddNode(_root, 
null);

                    
// Build a tree of SiteMapNodes underneath the root node
                    while (reader.Read())
                    
{
                        
// Create another site map node and add it to the site map
                        SiteMapNode node = CreateSiteMapNodeFromDataReader(reader);
                        AddNode(node, GetParentNodeFromDataReader(reader));
                    }


                    
// Use the SQL cache dependency
                    if (dependency != null)
                    
{
                        HttpRuntime.Cache.Insert(_cacheDependencyName, 
new object(), dependency,
                            Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, CacheItemPriority.NotRemovable,
                            
new CacheItemRemovedCallback(OnSiteMapChanged));
                    }

                }

            }

            
finally
            
{
                connection.Close();
            }


            
// Return the root SiteMapNode
            return _root;
        }

    }


    
protected override SiteMapNode GetRootNodeCore ()
    
{
        
lock (_lock)
        
{
            BuildSiteMap();
            
return _root;
        }

    }


    
// Helper methods
    private SiteMapNode CreateSiteMapNodeFromDataReader (DbDataReader reader)
    
{
        
// Make sure the node ID is present
        if (reader.IsDBNull (_indexID))
            
throw new ProviderException (_errmsg1);

        
// Get the node ID from the DataReader
        int id = reader.GetInt32 (_indexID);

        
// Make sure the node ID is unique
        if (_nodes.ContainsKey(id))
            
throw new ProviderException(_errmsg2);

        
// Get title, URL, description, and roles from the DataReader
        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 ();
        
string roles = reader.IsDBNull(_indexRoles) ? null : reader.GetString(_indexRoles).Trim();

        
// If roles were specified, turn the list into a string array
        string[] rolelist = null;
        
if (!String.IsNullOrEmpty(roles))
            rolelist 
= roles.Split(new char[] ','';' }512);

        
// Create a SiteMapNode
        SiteMapNode node = new SiteMapNode(this, id.ToString(), url, title, description, rolelist, nullnullnull);

        
// Record the node in the _nodes dictionary
        _nodes.Add(id, node);
       
        
// Return the node        
        return node;        
    }


    
private SiteMapNode GetParentNodeFromDataReader(DbDataReader reader)
    
{
        
// Make sure the parent ID is present
        if (reader.IsDBNull (_indexParent))
            
throw new ProviderException (_errmsg3);

        
// Get the parent ID from the DataReader
        int pid = reader.GetInt32(_indexParent);

        
// Make sure the parent ID is valid
        if (!_nodes.ContainsKey(pid))
            
throw new ProviderException(_errmsg4);

        
// Return the parent SiteMapNode
        return _nodes[pid];
    }


    
void OnSiteMapChanged(string key, object item, CacheItemRemovedReason reason)
    
{
        
lock (_lock)
        
{
            
if (key == _cacheDependencyName && reason == CacheItemRemovedReason.DependencyChanged)
            
{
                
// Refresh the site map
                Clear ();
                _nodes.Clear();
                _root 
= null;
            }

        }

    }

}

原创粉丝点击