MSDN
Custom Site Map Providers in ASP.NET 2.0
Site Map Providers
Code
Web.config
<configuration> <connectionStrings> <add name="SiteMapConnectionString" connectionString="server=.;database=TestDatabase;uid=sa;pwd=P@ssw0rd"/> </connectionStrings> <system.web> <siteMap defaultProvider="SqlSiteMapProvider" enabled="true"> <providers> <clear /> <add name="SqlSiteMapProvider" type="ClassLibrary1.SqlSiteMapProvider, ClassLibrary1" securityTrimmingEnabled="false" connectionStringName="SiteMapConnectionString" /> <add name="web" type="System.Web.XmlSiteMapProvider, System.Web, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" siteMapFile="Web.sitemap" /> </providers> </siteMap> <caching> <sqlCacheDependency enabled="true" pollTime="500"> <databases> <add name="DocumentMaster" connectionStringName="SiteMapConnectionString" pollTime="500" /> </databases> </sqlCacheDependency> </caching> ...... </system.web> <configuration>
aspx
<asp:TreeView runat="server" ID="trSiteMap"
DataSourceID="smdsAdministration"
ImageSet="Arrows"
NodeStyle-HorizontalPadding="4px"
SelectedNodeStyle-Font-Bold="true"
SelectedNodeStyle-CssClass="ui-menu-selected"
ShowLines="true">
</asp:TreeView>
<asp:SiteMapDataSource runat="server" ID="smdsAdministration" SiteMapProvider="SqlSiteMapProvider" StartingNodeUrl="naver.com" />MSSQL Table
USE [TestDatabase] GO /****** Object: Table [dbo].[tb_Sitemap] Script Date: 04/04/2011 19:27:09 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO SET ANSI_PADDING ON GO CREATE TABLE [dbo].[tb_Sitemap]( [ID] [int] IDENTITY(1,1) NOT NULL, [Title] [varchar](32) NULL, [Description] [varchar](512) NULL, [Url] [varchar](512) NULL, [Roles] [varchar](512) NULL, [Parent] [int] NULL, CONSTRAINT [PK_tb_Sitemap] PRIMARY KEY CLUSTERED ( [ID] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO SET ANSI_PADDING OFF GO
MSSQL Stored Procedure
USE [TestDatabase]
GO
/****** Object: StoredProcedure [dbo].[proc_GetSiteMap] Script Date: 04/04/2011 19:28:11 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Angeleyes
-- Create date: 2011-04-01
-- Description: Sitemap List
-- =============================================
ALTER PROCEDURE [dbo].[proc_GetSiteMap]
-- Add the parameters for the stored procedure here
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
SELECT *
FROM [dbo].[tb_Sitemap]
END
MSSQL Table-Data
USE [TestDatabase] GO /****** Object: Table [dbo].[tb_Sitemap] Script Date: 04/04/2011 19:29:33 ******/ SET IDENTITY_INSERT [dbo].[tb_Sitemap] ON INSERT [dbo].[tb_Sitemap] ([ID], [Title], [Description], [Url], [Roles], [Parent]) VALUES (1, N'Home', NULL, N'~/Default.aspx', NULL, NULL) INSERT [dbo].[tb_Sitemap] ([ID], [Title], [Description], [Url], [Roles], [Parent]) VALUES (2, N'News', N'News', N'~/News.aspx', N'*', 1) INSERT [dbo].[tb_Sitemap] ([ID], [Title], [Description], [Url], [Roles], [Parent]) VALUES (3, N'Naver', N'Naver Page', N'http://naver.com', N'*', 1) INSERT [dbo].[tb_Sitemap] ([ID], [Title], [Description], [Url], [Roles], [Parent]) VALUES (4, N'new.gimsdev.com', N'new.gimsdev.com', N'http://new.gimsdev.com', N'*', 1) INSERT [dbo].[tb_Sitemap] ([ID], [Title], [Description], [Url], [Roles], [Parent]) VALUES (5, N'Admin', N'Administrator Menu', N'~/Admin.aspx', N'*', 1) INSERT [dbo].[tb_Sitemap] ([ID], [Title], [Description], [Url], [Roles], [Parent]) VALUES (6, N'Daum', N'Daum Page', N'http://daum.net/', N'*', 1) INSERT [dbo].[tb_Sitemap] ([ID], [Title], [Description], [Url], [Roles], [Parent]) VALUES (7, N'경향', N'경향', N'http://www.khan.co.kr/', NULL, 2) INSERT [dbo].[tb_Sitemap] ([ID], [Title], [Description], [Url], [Roles], [Parent]) VALUES (8, N'한겨례', N'한겨례', N'http://www.hani.co.kr/', NULL, 2) INSERT [dbo].[tb_Sitemap] ([ID], [Title], [Description], [Url], [Roles], [Parent]) VALUES (9, N'노컷뉴스', N'노컷뉴스', N'http://www.nocutnews.co.kr/', NULL, 2) INSERT [dbo].[tb_Sitemap] ([ID], [Title], [Description], [Url], [Roles], [Parent]) VALUES (10, N'SE', N'Naver SE', N'http://se.naver.com/', NULL, 3) INSERT [dbo].[tb_Sitemap] ([ID], [Title], [Description], [Url], [Roles], [Parent]) VALUES (11, N'ME', N'Naver ME', N'http://me.naver.com/', NULL, 3) SET IDENTITY_INSERT [dbo].[tb_Sitemap] OFF
SqlSiteMapProvider.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.Specialized;
using System.Configuration;
using System.Configuration.Provider;
using System.Data;
using System.Data.Common;
using System.Data.SqlClient;
using System.Runtime.CompilerServices;
using System.Security.Permissions;
using System.Web;
using System.Web.Configuration;
namespace HPW.Portal.Common.Navigation
{
[SqlClientPermission(SecurityAction.Demand, Unrestricted = true)]
public class SqlSiteMapProvider : StaticSiteMapProvider
{
#region Contructor
#endregion
#region Instance Variables
private const string _errmsg1 = "Missing node ID";
private const string _errmsg2 = "Duplicate node ID";
private const string _errmsg3 = "Missing parent ID";
private const string _errmsg4 = "Invalid parent ID";
private const string _errmsg5 = "Empty or missing connectionStringName";
private const string _errmsg6 = "Missing connection string";
private const string _errmsg7 = "Empty connection string";
private string _connect, strProcedureName;
private int _indexID, _indexTitle, _indexUrl, _indexDesc, _indexRoles, _indexParent;
private Dictionary<int, SiteMapNode> _nodes = new Dictionary<int, SiteMapNode>(16);
private Dictionary<string, object> Parameters = new Dictionary<string, object>();
private bool IsParameter = false;
private SiteMapNode _root;
#endregion
#region Properties
#region // string ProcedureName //
/// <summary>
/// Properties Procedure Name
/// </summary>
protected string ProcedureName
{
get
{
if (String.IsNullOrEmpty(strProcedureName))
return "proc_GetSiteMap";
else
return strProcedureName;
}
set
{
strProcedureName = value;
}
}
#endregion
#endregion
#region Initialize and Shutdown methods
#region // override void Initialize(string name, NameValueCollection config) //
/// <summary>
/// Initialize
/// </summary>
/// <param name="name">config Name</param>
/// <param name="config">config attribute</param>
public override void Initialize(string name, NameValueCollection config)
{
if (config == null)
throw new ArgumentNullException("config");
if (String.IsNullOrEmpty(name))
name = "SqlSiteMapProvider";
base.Initialize(name, config);
string connect = config["connectionStringName"];
if (String.IsNullOrEmpty(connect))
throw new ProviderException(_errmsg5);
config.Remove("connectionStringName");
if (WebConfigurationManager.ConnectionStrings[connect] == null)
throw new ProviderException(_errmsg6);
_connect = WebConfigurationManager.ConnectionStrings
[connect].ConnectionString;
if (String.IsNullOrEmpty(_connect))
throw new ProviderException(_errmsg7);
if (config["securityTrimmingEnabled"] != null)
config.Remove("securityTrimmingEnabled");
if (config["ProcedureName"] != null)
{
ProcedureName = config["ProcedureName"];
config.Remove("ProcedureName");
}
if (config["Parameters"] != null)
{
foreach (string parameter in config["Parameters"].Split('|'))
{
string[] data = parameter.Split(';');
Parameters.Add(data[0], data[1]);
}
config.Remove("Parameters");
}
if (config.Count > 0)
{
string attr = config.GetKey(0);
if (!String.IsNullOrEmpty(attr))
throw new ProviderException("Unrecognized attribute: " + attr);
}
}
#endregion
#endregion
#region Private Methods
#region // SiteMapNode CreateSiteMapNodeFromDataReader(DbDataReader reader) //
/// <summary>
/// Create SiteMapNode From DataReader
/// </summary>
/// <param name="reader">Data Source</param>
/// <returns>create node</returns>
private SiteMapNode CreateSiteMapNodeFromDataReader(DbDataReader reader)
{
if (reader.IsDBNull(_indexID))
throw new ProviderException(_errmsg1);
int id = reader.GetInt32(_indexID);
if (_nodes.ContainsKey(id))
throw new ProviderException(_errmsg2);
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();
string roles = reader.IsDBNull(_indexRoles) ? null : reader.GetString(_indexRoles).Trim();
string[] rolelist = null;
if (!String.IsNullOrEmpty(roles))
rolelist = roles.Split(new char[] { ',', ';' }, 512);
SiteMapNode node = new SiteMapNode(this, id.ToString(), url, title, description, rolelist, null, null, null);
_nodes.Add(id, node);
return node;
}
#endregion
#region // SiteMapNode GetParentNodeFromDataReader(DbDataReader reader) //
/// <summary>
/// Get Parent Node From DataReader
/// </summary>
/// <param name="reader">Data Source</param>
/// <returns>Selected node</returns>
private SiteMapNode GetParentNodeFromDataReader(DbDataReader reader)
{
if (reader.IsDBNull(_indexParent))
throw new ProviderException(_errmsg3);
int pid = reader.GetInt32(_indexParent);
if (!_nodes.ContainsKey(pid))
throw new ProviderException(_errmsg4);
return _nodes[pid];
}
#endregion
#region // SiteMapNode FindChildNodeByID(SiteMapNode ParentNode, string strId) //
/// <summary>
/// 현재 노드의 하위 노드 중 아이디와 동일한 노드를 찾아 반환한다.
/// </summary>
/// <param name="ParentNode">부모 노드</param>
/// <param name="strId">찾을 아이디</param>
/// <returns>찾은 노드</returns>
private SiteMapNode FindChildNodeByID(SiteMapNode ParentNode, string strId)
{
SiteMapNode smnFindNode = null;
if (ParentNode != null && ParentNode.ChildNodes.Count > 0)
foreach (SiteMapNode node in ParentNode.ChildNodes)
{
if (node.Key.Equals(strId))
{
smnFindNode = node;
break;
}
else if (node.ChildNodes.Count > 0)
smnFindNode = FindChildNodeByID(node, strId);
if (smnFindNode != null) break;
}
return smnFindNode;
}
#endregion
#endregion
#region Public Methods
#endregion
#region override Methods
#region // override SiteMapNode BuildSiteMap() //
/// <summary>
/// Build SiteMap
/// </summary>
/// <returns>Root SiteMapNode</returns>
public override SiteMapNode BuildSiteMap()
{
lock (this)
{
if (_root != null)
return _root;
using (SqlConnection connection = new SqlConnection(_connect))
{
try
{
connection.Open();
SqlCommand command = new SqlCommand(ProcedureName, connection);
command.CommandType = CommandType.StoredProcedure;
if (IsParameter)
{
foreach (KeyValuePair<string, object> data in Parameters)
command.Parameters.Add(new SqlParameter(data.Key, data.Value));
}
SqlDataReader reader = command.ExecuteReader();
_indexID = reader.GetOrdinal("ID");
_indexUrl = reader.GetOrdinal("Url");
_indexTitle = reader.GetOrdinal("Title");
_indexDesc = reader.GetOrdinal("Description");
_indexRoles = reader.GetOrdinal("Roles");
_indexParent = reader.GetOrdinal("Parent");
if (reader.Read())
{
_root = CreateSiteMapNodeFromDataReader(reader);
AddNode(_root, null);
while (reader.Read())
{
SiteMapNode node = CreateSiteMapNodeFromDataReader(reader);
AddNode(node, GetParentNodeFromDataReader(reader));
}
}
}
finally
{
connection.Close();
}
}
return _root;
}
}
#endregion
#region // override void AddNode(SiteMapNode node, SiteMapNode parentNode) //
/// <summary>
/// Add Node
/// </summary>
/// <param name="node">add node</param>
/// <param name="parentNode">target parent node</param>
protected override void AddNode(SiteMapNode node, SiteMapNode parentNode)
{
bool isVirture = node.Url.ToLower().StartsWith("http://");
string strId = node.Key;
string strUrl = node.Url;
node.Url = isVirture ? node.Url.Remove(0, 7) : node.Url;
base.AddNode(node, parentNode);
if (isVirture && base.RootNode != null && base.RootNode.ChildNodes.Count > 0)
{
SiteMapNode childNode = FindChildNodeByID(base.RootNode, strId);
if (childNode != null)
childNode.Url = strUrl;
}
}
#endregion
#region // override SiteMapNode GetRootNodeCore() //
/// <summary>
/// Get RootNode Core
/// </summary>
/// <returns>Root SiteMapNode</returns>
protected override SiteMapNode GetRootNodeCore()
{
BuildSiteMap();
return _root;
}
#endregion
#endregion
}
}
Output
'Developer' 카테고리의 다른 글
| EXTJS Custom XmlTreeLoader (0) | 2011.05.12 |
|---|---|
| Sharepoint 2010 Deploying Resource File in an App_GlobalResources (0) | 2011.04.05 |
| C# SiteMapProvider [HttpException] {0} is not a valid virtual path(올바른 가상 경로가 아닙니다.) (0) | 2011.04.04 |
| Sharepoint 2010 Script Resource(다국어) 처리 방법 (0) | 2011.04.01 |
| [어셈블리 바인딩 로깅이 꺼져 있습니다.] 어셈블리 바인딩 로깅 시작 방법 (2) | 2011.03.30 |