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

简介:
[索引页]
[源码下载]



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


作者: 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>
 
 






     本文转自webabcd 51CTO博客,原文链接:http://blog.51cto.com/webabcd/344839,如需转载请自行联系原作者


相关文章
|
10月前
|
Java 物联网 C#
C#/.NET/.NET Core学习路线集合,学习不迷路!
C#/.NET/.NET Core学习路线集合,学习不迷路!
392 0
|
5月前
|
SQL 小程序 API
如何运用C#.NET技术快速开发一套掌上医院系统?
本方案基于C#.NET技术快速构建掌上医院系统,结合模块化开发理念与医院信息化需求。核心功能涵盖用户端的预约挂号、在线问诊、报告查询等,以及管理端的排班管理和数据统计。采用.NET Core Web API与uni-app实现前后端分离,支持跨平台小程序开发。数据库选用SQL Server 2012,并通过读写分离与索引优化提升性能。部署方案包括Windows Server与负载均衡设计,确保高可用性。同时针对API差异、数据库老化及高并发等问题制定应对措施,保障系统稳定运行。推荐使用Postman、Redgate等工具辅助开发,提升效率与质量。
177 0
|
9月前
|
开发框架 搜索推荐 算法
一个包含了 50+ C#/.NET编程技巧实战练习教程
一个包含了 50+ C#/.NET编程技巧实战练习教程
249 18
|
9月前
|
缓存 算法 安全
精选10款C#/.NET开发必备类库(含使用教程),工作效率提升利器!
精选10款C#/.NET开发必备类库(含使用教程),工作效率提升利器!
252 12
|
9月前
|
开发框架 人工智能 .NET
C#/.NET/.NET Core拾遗补漏合集(24年12月更新)
C#/.NET/.NET Core拾遗补漏合集(24年12月更新)
124 6
|
9月前
|
开发框架 算法 .NET
C#/.NET/.NET Core技术前沿周刊 | 第 15 期(2024年11.25-11.30)
C#/.NET/.NET Core技术前沿周刊 | 第 15 期(2024年11.25-11.30)
119 6
|
9月前
|
开发框架 Cloud Native .NET
C#/.NET/.NET Core技术前沿周刊 | 第 16 期(2024年12.01-12.08)
C#/.NET/.NET Core技术前沿周刊 | 第 16 期(2024年12.01-12.08)
119 6
|
9月前
|
开发框架 监控 .NET
C#进阶-ASP.NET WebForms调用ASMX的WebService接口
通过本文的介绍,希望您能深入理解并掌握ASP.NET WebForms中调用ASMX WebService接口的方法和技巧,并在实际项目中灵活运用这些技术,提高开发效率和应用性能。
500 5
|
9月前
|
算法 Java 测试技术
Benchmark.NET:让 C# 测试程序性能变得既酷又简单
Benchmark.NET是一款专为 .NET 平台设计的性能基准测试框架,它可以帮助你测量代码的执行时间、内存使用情况等性能指标。它就像是你代码的 "健身教练",帮助你找到瓶颈,优化性能,让你的应用跑得更快、更稳!希望这个小教程能让你在追求高性能的路上越走越远,享受编程带来的无限乐趣!
397 13
|
10月前
|
Java 物联网 编译器
C#一分钟浅谈:.NET Core 与 .NET 5 区别
本文对比了 .NET Core 和 .NET 5,从历史背景、主要区别、常见问题及易错点等方面进行了详细分析。.NET Core 侧重跨平台支持和高性能,而 .NET 5 在此基础上统一了 .NET 生态系统,增加了更多新特性和优化。开发者可根据具体需求选择合适的版本。
341 7