因为我的做的一个项目是基于Category分类来进行导航的, 查看
ASP.NET 站点导航概述 和
如何:实现 ASP.NET 站点地图提供程序 两篇参考文章, 也模仿地写了一个SiteMapProvider程序....
各个 ASP.NET 站点导航组件之间的关系图
而我们这次就是编程图中的"自定义站点地图提供程序"....
我的DAL层是基于NBear的....
Category实体定义如下:
[AutoPreLoad]
public interface Category : Entity
{
[PrimaryKey]
int ID { get; }
[SqlType("nvarchar(50)")]
string Title { get; set; }
/// <summary>
/// 排序位置
/// </summary>
int Sort { get;set;}
[FkReverseQuery(LazyLoad = true)]
[MappingName("ParentID")]
Category Parent { get;set;}
[FkQuery("Parent", LazyLoad = false, OrderBy= "Sort")]
[SerializationIgnore]
Category[] Children { get; set; }
[FkQuery("Category", OrderBy = "{ID} DESC", LazyLoad = true)]
Article[] Articles { get;set;}
}
程序代码如下:
MK2.AspNet.Controls.AccessSiteMapProvider
namespace MK2.AspNet.Controls
{
using System;
using System.Collections;
using System.Collections.Specialized;
using System.Data;
using System.Data.OleDb;
using System.Security.Permissions;
using System.Web;
using Entities;
/// An extremely simple AccessSiteMapProvider that only supports a
/// site map node hierarchy 1 level deep.
[AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Minimal)]
public class AccessSiteMapProvider : StaticSiteMapProvider
{
private SiteMapNode rootNode = null;
private CategoryDAL categoryDAL = null;
// Implement a default constructor.
public AccessSiteMapProvider() { }
// Some basic state to help track the initialization state of the provider.
private bool initialized = false;
public virtual bool IsInitialized
{
get
{
return initialized;
}
}
// Return the root node of the current site map.
public override SiteMapNode RootNode
{
get
{
SiteMapNode temp = null;
temp = BuildSiteMap();
return temp;
}
}
protected override SiteMapNode GetRootNodeCore()
{
return RootNode;
}
// Initialize is used to initialize the properties and any state that the
// AccessProvider holds, but is not used to build the site map.
// The site map is built when the BuildSiteMap method is called.
public override void Initialize(string name, NameValueCollection attributes)
{
if (IsInitialized)
return;
base.Initialize(name, attributes);
// Create and test the connection to the Microsoft Access database.
categoryDAL = new CategoryDAL();
initialized = true;
}
///
/// SiteMapProvider and StaticSiteMapProvider methods that this derived class must override.
///
// Clean up any collections or other state that an instance of this may hold.
protected override void Clear()
{
lock (this)
{
rootNode = null;
base.Clear();
}
}
// Build an in-memory representation from persistent
// storage, and return the root node of the site map.
public override SiteMapNode BuildSiteMap()
{
// Since the SiteMap class is static, make sure that it is
// not modified while the site map is built.
lock (this)
{
// If there is no initialization, this method is being
// called out of order.
if (!IsInitialized)
{
throw new Exception("BuildSiteMap called incorrectly.");
}
// If there is no root node, then there is no site map.
if (null == rootNode)
{
// Start with a clean slate
Clear();
// Select the root node of the site map from Microsoft Access.
rootNode = new SiteMapNode(this, "-1", "~/", "首页", "Home page.");
Category[] childNodes = categoryDAL.GetCategories(0);
foreach (Category child in childNodes)
{
SiteMapNode childNode;
childNode = GetNode(child);
AddNode(childNode, rootNode);
}
}
return rootNode;
}
}
private SiteMapNode GetNode(Category node)
{
SiteMapNode returnNode = new SiteMapNode(this, node.ID.ToString(),
"~/Category.aspx?Category=" + node.ID, node.Title, node.Title);
if (node.Children.Count > 0)
{
foreach (Category child in node.Children)
{
SiteMapNode childNode;
childNode = GetNode(child);
AddNode(childNode, returnNode);
}
}
return returnNode;
}
}
}
此SiteMapProvider只适合我的项目, 在此只是作个示例展示如何扩展StaticSiteMapProvider而已....