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,?PublicKeyToken=b03f5f7f11d50a3a"?siteMapFile="~/Sitemap/Web.sitemap"/>
 ????????
<add?name="SqlSiteMapProvider"?type="SqlSiteMapProvider"?connectionStringName="SqlConnectionString"?/>
 ??????
</providers>
 ????
</siteMap>
 ??
</system.web>

</configuration>
(编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|