SiteMap dataprovider

本文介绍ASP.NET 2.0中的站点导航功能,包括如何使用.sitemap文件定义站点结构,创建自定义站点地图提供程序的方法,以及示例代码展示如何从XML文件和数据库读取站点地图数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >




介绍
ASP.NET 2.0 中的站点导航提供程序向应用程序中的页公开导航信息,使您可以独立于页的实际物理布局定义站点的结构。默认站点导航提供程序基于XML,但通过为站点地图编写自定义提供程序,也可以从任意后端公开此信息。


关键
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.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>();

   

    // for 线程安全

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

    }





}

 

站点地图测试(从数据库读数据)
SiteMap/FromDatabase.aspx

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

自定义站点地图提供程序(SqlServer方式)
SqlSiteMapProvider.cs(“sp_GetSiteMap”为读取站点地图数据的存储过程,详见源码)
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值