zoukankan      html  css  js  c++  java
  • SiteMapPath使用

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

            }

        }

    }




  • 相关阅读:
    让EditPlus支持SQL高亮提示
    SQL Server 触发器
    asp.net中使用Global.asax文件中添加应用出错代码,写入系统日志文件或数据库
    C#钩子类 几乎捕获键盘鼠标所有事件
    DataGridView一些常用操作
    在C#中实现串口通信的方法
    System.Diagnostics.Process.Start的妙用
    Byte[]、Image、Bitmap 之间的相互转换
    Dos命令打印文件以及Dos打印到USB打印端口
    Winform常用的一些功能收集(持续更新)
  • 原文地址:https://www.cnblogs.com/zijinguang/p/1226098.html
Copyright © 2011-2022 走看看