重新过一遍ASP.NET 2.0(C#)(3) - SiteMap(站点地图)

原文链接: http://www.cnblogs.com/hulu/archive/2007/06/27/797861.html
介绍
ASP.NET 2.0 中的站点导航提供程序向应用程序中的页公开导航信息,使您可以独立于页的实际物理布局定义站点的结构。默认站点导航提供程序基于XML,但通过为站点地图编写自定义提供程序,也可以从任意后端公开此信息。


关键
1、创建.sitemap文件,其实就是一个xml文件,包括有着层次结构的 元素

2、 元素的属性:
  Url - 链接地址
  Title - 显示的标题
  Description - 描述(ToolTip)
  resourceKey - 本地化用的(要在节点加上这个属性enableLocalization=true)   
  securityTrimmingEnabled - 是否让sitemap支持安全特性
  roles - 哪些角色可以访问当前节点,多角色用逗号隔开(需要将securityTrimmingEnabled设置为true)
  siteMapFile - 引用另一个sitemap文件
  注:应用权限的时候,Web.config中要有相对应的配置

3、可以通过SiteMap和SiteMapNode类访问站点地图数据

4、自定义站点地图提供程序应该写一个继承自StaticSiteMapProvider的类

5、XmlSiteMapProvider要求站点地图节点具有唯一的URL


示例
SiteMap/Web.sitemap(包括一个有siteMapFile属性的节点)
None.gif xml version="1.0" encoding="utf-8"  ?>
None.gif
< siteMap  xmlns ="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0"   >
None.gif  
< siteMapNode  url ="~/SiteMap/Test.aspx#1"  title ="首页"   description ="首页描述" >
None.gif    
< siteMapNode  url ="~/SiteMap/Test.aspx#2"  title ="频道1"   description ="频道1描述"   />
None.gif    
< siteMapNode  url ="~/SiteMap/Test.aspx#3"  title ="频道2"  description ="频道2描述"   />
None.gif    
< siteMapNode  siteMapFile ="WebChild.sitemap" >
None.gif    
siteMapNode >
None.gif    
< siteMapNode  url ="~/SiteMap/Test.aspx#4"  title ="频道4"  description ="频道4描述"   />
None.gif  
siteMapNode >
None.gif
siteMap >
None.gif

SiteMap/WebChild.sitemap(上面.sitemap文件某个节点的siteMapFile属性所指定的文件)
None.gif xml version="1.0" encoding="utf-8"  ?>
None.gif
< siteMap  xmlns ="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0"   >
None.gif  
< siteMapNode  url ="~/SiteMap/Test.aspx#5"  title ="频道3"   description ="频道3" >
None.gif    
< siteMapNode  url ="~/SiteMap/Test.aspx#6"  title ="栏目1"   description ="栏目1描述"   />
None.gif    
< siteMapNode  url ="~/SiteMap/Test.aspx#7"  title ="栏目2"   description ="栏目2描述"   />
None.gif    
< siteMapNode  url ="~/SiteMap/Test.aspx#8"  title ="栏目3"   description ="栏目3描述"   />
None.gif  
siteMapNode >
None.gif
siteMap >
None.gif

站点地图测试
SiteMap/Test.aspx
ExpandedBlockStart.gif ContractedBlock.gif <% dot.gif @ Page Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true" CodeFile="Test.aspx.cs"
ExpandedBlockEnd.gif    Inherits
="SiteMap_Test" Title="站点地图测试" 
%>
None.gif
None.gif
< asp:Content  ID ="Content1"  ContentPlaceHolderID ="ContentPlaceHolder1"  runat ="Server" >
None.gif    
< p >
None.gif        
< asp:TreeView  ID ="TreeView1"  runat ="server"  DataSourceID ="SiteMapDataSource1" >
None.gif        
asp:TreeView >
None.gif        
< asp:Menu  ID ="Menu1"  runat ="server"  DataSourceID ="SiteMapDataSource2"  Orientation ="Horizontal" >
None.gif        
asp:Menu >
ExpandedBlockStart.gifContractedBlock.gif        
<% dot.gif --显示根节点的数据源-- %>
None.gif        
< asp:SiteMapDataSource  ID ="SiteMapDataSource1"  runat ="server"  SiteMapProvider ="XmlSiteMapProviderTest"   />
ExpandedBlockStart.gifContractedBlock.gif        
<% dot.gif --不显示根节点的数据源-- %>
None.gif        
< asp:SiteMapDataSource  ID ="SiteMapDataSource2"  runat ="server"  SiteMapProvider ="XmlSiteMapProviderTest"
None.gif            ShowStartingNode
="false"   />
None.gif    
p >
None.gif    
< p >
None.gif        编码方式访问节点信息如下
< br  />
None.gif        
< asp:Label  ID ="lbl"  runat ="server"  BackColor ="#DDDDDD"   />
None.gif    
p >
None.gif
asp:Content >
None.gif

SiteMap/Test.aspx.cs
None.gif using  System;
None.gif
using  System.Data;
None.gif
using  System.Configuration;
None.gif
using  System.Collections;
None.gif
using  System.Web;
None.gif
using  System.Web.Security;
None.gif
using  System.Web.UI;
None.gif
using  System.Web.UI.WebControls;
None.gif
using  System.Web.UI.WebControls.WebParts;
None.gif
using  System.Web.UI.HtmlControls;
None.gif
None.gif
public  partial  class  SiteMap_Test : System.Web.UI.Page
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
protected void Page_Load(object sender, EventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
// 获取当前节点的Title
InBlock.gif
        lbl.Text = "当前节点标题:" + SiteMap.CurrentNode.Title + "";
InBlock.gif
InBlock.gif        
// 取得url为“~/Default.aspx”的SiteMapNode
InBlock.gif
        SiteMapNode smn = SiteMap.Provider.FindSiteMapNode("~/Default.aspx");
InBlock.gif        lbl.Text 
+= "Default.aspx节点的Url:" + smn.Url;
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif

站点地图测试(从数据库读数据)
SiteMap/FromDatabase.aspx
ExpandedBlockStart.gif ContractedBlock.gif <% dot.gif @ Page Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true" CodeFile="FromDatabase.aspx.cs"
ExpandedBlockEnd.gif    Inherits
="SiteMap_FromDatabase" Title="站点地图测试(从数据库读数据)" 
%>
None.gif
None.gif
< asp:Content  ID ="Content1"  ContentPlaceHolderID ="ContentPlaceHolder1"  runat ="Server" >
None.gif    
< asp:TreeView  ID ="TreeView1"  runat ="server"  DataSourceID ="SiteMapDataSource1" >
None.gif    
asp:TreeView >
None.gif    
< asp:SiteMapDataSource  ID ="SiteMapDataSource1"  runat ="server"  SiteMapProvider ="SqlSiteMapProvider"   />
None.gif
asp:Content >
None.gif

自定义站点地图提供程序(SqlServer方式)
SqlSiteMapProvider.cs(“sp_GetSiteMap”为读取站点地图数据的存储过程,详见源码)
None.gif using  System;
None.gif
using  System.Web;
None.gif
using  System.Data.SqlClient;
None.gif
using  System.Collections.Specialized;
None.gif
using  System.Configuration;
None.gif
using  System.Web.Configuration;
None.gif
using  System.Collections.Generic;
None.gif
using  System.Configuration.Provider;
None.gif
using  System.Security.Permissions;
None.gif
using  System.Data.Common;
None.gif
using  System.Data;
None.gif
ExpandedBlockStart.gifContractedBlock.gif
/**/ /// 
InBlock.gif
/// SqlSiteMapProvider
ExpandedBlockEnd.gif
/// 

None.gif public   class  SqlSiteMapProvider : StaticSiteMapProvider
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
private string _strCon;
InBlock.gif    
private int _indexID, _indexTitle, _indexUrl, _indexDesc, _indexParent;
InBlock.gif
InBlock.gif    
// 节点
InBlock.gif
    private SiteMapNode _node;
InBlock.gif    
InBlock.gif    
// 节点字典表
InBlock.gif
    private Dictionary<int, SiteMapNode> _nodes = new Dictionary<int, SiteMapNode>();
InBlock.gif   
InBlock.gif    
// 用于单例模式
InBlock.gif
    private readonly object _lock = new object();
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/**//// 
InBlock.gif    
/// 初始化
InBlock.gif    
/// 

InBlock.gif    
/// name
ExpandedSubBlockEnd.gif    
/// config

InBlock.gif    public override void Initialize(string name, NameValueCollection config)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
// 验证是否有config
InBlock.gif
        if (config == null)
InBlock.gif            
throw new ArgumentNullException("config不能是null");
InBlock.gif
InBlock.gif        
// 没有provider则设置为默认的
InBlock.gif
        if (String.IsNullOrEmpty(name))
InBlock.gif            name 
= "SqlSiteMapProvider";
InBlock.gif
InBlock.gif        
// 没有描述就增加一个描述
InBlock.gif
        if (string.IsNullOrEmpty(config["description"]))
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            config.Remove(
"description");
InBlock.gif            config.Add(
"description""SqlSiteMapProvider");
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
// 调用基类的初始化方法
InBlock.gif
        base.Initialize(name, config);
InBlock.gif
InBlock.gif        
// 初始化连接字符串
InBlock.gif
        string conStringName = config["connectionStringName"];
InBlock.gif
InBlock.gif        
if (String.IsNullOrEmpty(conStringName))
InBlock.gif            
throw new ProviderException("没找到connectionStringName");
InBlock.gif
InBlock.gif        config.Remove(
"connectionStringName");
InBlock.gif
InBlock.gif        
if (WebConfigurationManager.ConnectionStrings[conStringName] == null)
InBlock.gif            
throw new ProviderException("根据connectionStringName没找到连接字符串");
InBlock.gif
InBlock.gif        
// 获得连接字符串
InBlock.gif
        _strCon = WebConfigurationManager.ConnectionStrings[conStringName].ConnectionString;
InBlock.gif
InBlock.gif        
if (String.IsNullOrEmpty(_strCon))
InBlock.gif            
throw new ProviderException("连接字符串是空的");
ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/**//// 
InBlock.gif    
/// 从持久性存储区加载站点地图信息,并在内存中构建它
InBlock.gif    
/// 

ExpandedSubBlockEnd.gif    
/// 

InBlock.gif    public override SiteMapNode BuildSiteMap()
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
lock (_lock)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
// 单例模式的实现
InBlock.gif
            if (_node != null)
InBlock.gif                
return _node;
InBlock.gif
InBlock.gif            SqlConnection connection 
= new SqlConnection(_strCon);
InBlock.gif
InBlock.gif            
try
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                SqlCommand command 
= new SqlCommand("sp_GetSiteMap", connection);
InBlock.gif                command.CommandType 
= CommandType.StoredProcedure;
InBlock.gif
InBlock.gif                connection.Open();
InBlock.gif                SqlDataReader reader 
= command.ExecuteReader();
InBlock.gif
InBlock.gif                
// 获得各个字段的索引
InBlock.gif
                _indexID = reader.GetOrdinal("ID");
InBlock.gif                _indexUrl 
= reader.GetOrdinal("Url");
InBlock.gif                _indexTitle 
= reader.GetOrdinal("Title");
InBlock.gif                _indexDesc 
= reader.GetOrdinal("Description");
InBlock.gif                _indexParent 
= reader.GetOrdinal("Parent");
InBlock.gif
InBlock.gif                
if (reader.Read())
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    
// 把第一条记录作为根节点添加
InBlock.gif
                    _node = CreateSiteMapNodeFromDataReader(reader);
InBlock.gif                    AddNode(_node, 
null);
InBlock.gif
InBlock.gif                    
// 构造节点树
InBlock.gif
                    while (reader.Read())
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
dot.gif{
InBlock.gif                        
// 在站点地图中增加一个节点
InBlock.gif
                        SiteMapNode node = CreateSiteMapNodeFromDataReader(reader);
InBlock.gif                        AddNode(node, GetParentNodeFromDataReader(reader));
ExpandedSubBlockEnd.gif                    }

InBlock.gif
ExpandedSubBlockEnd.gif                }

InBlock.gif
InBlock.gif                reader.Close();
ExpandedSubBlockEnd.gif            }

InBlock.gif            
catch (Exception ex)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
throw new Exception(ex.ToString());
ExpandedSubBlockEnd.gif            }

InBlock.gif            
finally
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                connection.Close();
ExpandedSubBlockEnd.gif            }

InBlock.gif
InBlock.gif            
// 返回SiteMapNode
InBlock.gif
            return _node;
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/**//// 
InBlock.gif    
/// 将检索目前由当前提供程序管理的所有节点的根节点
InBlock.gif    
/// 

ExpandedSubBlockEnd.gif    
/// 

InBlock.gif    protected override SiteMapNode GetRootNodeCore()
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
lock (_lock)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
return BuildSiteMap();
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/**//// 
InBlock.gif    
/// 根据DataReader读出来的数据返回SiteMapNode
InBlock.gif    
/// 

InBlock.gif    
/// DbDataReader
ExpandedSubBlockEnd.gif    
/// 

InBlock.gif    private SiteMapNode CreateSiteMapNodeFromDataReader(DbDataReader reader)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
if (reader.IsDBNull(_indexID))
InBlock.gif            
throw new ProviderException("没找到ID");
InBlock.gif
InBlock.gif        
int id = reader.GetInt32(_indexID);
InBlock.gif
InBlock.gif        
if (_nodes.ContainsKey(id))
InBlock.gif            
throw new ProviderException("不能有重复ID");
InBlock.gif
InBlock.gif        
// 根据字段索引获得相应字段的值
InBlock.gif
        string title = reader.IsDBNull(_indexTitle) ? null : reader.GetString(_indexTitle).Trim();
InBlock.gif        
string url = reader.IsDBNull(_indexUrl) ? null : reader.GetString(_indexUrl).Trim();
InBlock.gif        
string description = reader.IsDBNull(_indexDesc) ? null : reader.GetString(_indexDesc).Trim();
InBlock.gif
InBlock.gif        
// 新建一个SiteMapNode
InBlock.gif
        SiteMapNode node = new SiteMapNode(this, id.ToString(), url, title, description);
InBlock.gif
InBlock.gif        
// 把这个SiteMapNode添加进节点字典表里
InBlock.gif
        _nodes.Add(id, node);
InBlock.gif
InBlock.gif        
// 返回这个SiteMapNode
InBlock.gif
        return node;
ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/**//// 
InBlock.gif    
/// 得到父节点的SiteMapNode
InBlock.gif    
/// 

InBlock.gif    
/// 
ExpandedSubBlockEnd.gif    
/// 

InBlock.gif    private SiteMapNode GetParentNodeFromDataReader(DbDataReader reader)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
if (reader.IsDBNull(_indexParent))
InBlock.gif            
throw new ProviderException("父节点不能是空");
InBlock.gif
InBlock.gif        
int pid = reader.GetInt32(_indexParent);
InBlock.gif
InBlock.gif        
if (!_nodes.ContainsKey(pid))
InBlock.gif            
throw new ProviderException("有重复节点ID");
InBlock.gif
InBlock.gif        
// 返回父节点的SiteMapNode
InBlock.gif
        return _nodes[pid];
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif
ExpandedBlockEnd.gif}

上面两个测试页面所需的web.config中的配置
None.gif < configuration >
None.gif  
< appSettings />
None.gif  
< connectionStrings >
None.gif    
< add  name ="SqlConnectionString"  connectionString ="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\Database.mdf;Integrated Security=True;User Instance=True" />
None.gif  
connectionStrings >
None.gif  
< system .web >
None.gif    
< siteMap  enabled ="true"  defaultProvider ="XmlSiteMapProvider" >
None.gif      
< providers >
None.gif        
< add  name ="XmlSiteMapProvider"  type ="System.Web.XmlSiteMapProvider, System.Web, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"  siteMapFile ="~/Web.sitemap" />
None.gif        
< add  name ="XmlSiteMapProviderTest"  type ="System.Web.XmlSiteMapProvider, System.Web, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"  siteMapFile ="~/Sitemap/Web.sitemap" />
None.gif        
< add  name ="SqlSiteMapProvider"  type ="SqlSiteMapProvider"  connectionStringName ="SqlConnectionString"   />
None.gif      
providers >
None.gif    
siteMap >
None.gif  
system.web >
None.gif
configuration >


OK
[源码下载]

转载于:https://www.cnblogs.com/hulu/archive/2007/06/27/797861.html

你可能感兴趣的:(重新过一遍ASP.NET 2.0(C#)(3) - SiteMap(站点地图))