您的位置:首页 > 编程语言 > ASP

温故知新ASP.NET 2.0(C#)(3) - SiteMap(站点地图)

2007-02-14 22:31 567 查看
[索引页]

[源码下载]

[align=center]温故知新ASP.NET 2.0(C#)(3) - SiteMap(站点地图)[/align]

作者:webabcd

介绍

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


   


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


    }






}

上面两个测试页面所需的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>

OK

[源码下载]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息