SiteMapPath使用

转贴自  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,  null null null );

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

        }

    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值