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)
@H_423_3270@


{

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, PublicKeyToken=b03f5f7f11d50a3a" siteMapFile="~/Sitemap/Web.sitemap"/>

<add name="sqlSiteMapProvider" type="sqlSiteMapProvider" connectionStringName="sqlConnectionString" />

</providers>

</siteMap>

</system.web>

</configuration>
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。