-Dman100-
Posting Yak Master
210 Posts |
Posted - 2006-10-15 : 20:56:13
|
I'm using a sql sitemap provider as explained in the following MSDN article:http://msdn.microsoft.com/msdnmag/issues/06/02/WickedCode/ I have everything working okay, but now I'm trying to modify the "SqlSiteMapProvider.cs" class file to be able to include custom attributes to the sitemap...i.e. 'ImageUrl' which will hold the path to images for a siteMapNodeHere is my table:CREATE TABLE [dbo].[sitemap] ( [ID] [int] NOT NULL, [Title] [varchar] (32), [Description] [varchar] (512), [Url] [varchar] (512), [Roles] [varchar] (512), [Parent] [int], [ImageUrl] [varchar] (512)) ON [PRIMARY]GOALTER TABLE [dbo].[sitemap] ADD CONSTRAINT [PK_SiteMap] PRIMARY KEY CLUSTERED ( [ID] ) ON [PRIMARY] GOHere is the stored procedure that populates the sitemap:CREATE PROCEDURE proc_GetSiteMap AS SELECT [ID], [Title], [Description], [Url], [Roles], [Parent], [ImageUrl] FROM [SiteMap] ORDER BY [ID]GOHere is the class file: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;using System.Web.Caching;/// <summary>/// Summary description for SqlSiteMapProvider/// </summary>[SqlClientPermission (SecurityAction.Demand, Unrestricted=true)]public class SqlSiteMapProvider : StaticSiteMapProvider{ 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 const string _errmsg8 = "Invalid sqlCacheDependency"; private const string _cacheDependencyName = "__SiteMapCacheDependency"; private string _connect; // Database connection string private string _database, _table; // Database info for SQL Server 7/2000 cache dependency private bool _2005dependency = false; // Database info for SQL Server 2005 cache dependency private int _indexID, _indexTitle, _indexUrl, _indexDesc, _indexRoles, _indexParent; //, _indexImageUrl; private Dictionary<int, SiteMapNode> _nodes = new Dictionary<int, SiteMapNode>(16); private readonly object _lock = new object(); private SiteMapNode _root; public override void Initialize (string name, NameValueCollection config) { // Verify that config isn't null if (config == null) throw new ArgumentNullException("config"); // Assign the provider a default name if it doesn't have one if (String.IsNullOrEmpty(name)) name = "SqlSiteMapProvider"; // Add a default "description" attribute to config if the // attribute doesn’t exist or is empty if (string.IsNullOrEmpty(config["description"])) { config.Remove("description"); config.Add("description", "SQL site map provider"); } // Call the base class's Initialize method base.Initialize(name, config); // Initialize _connect 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); // Initialize SQL cache dependency info string dependency = config["sqlCacheDependency"]; if (!String.IsNullOrEmpty(dependency)) { if (String.Equals(dependency, "CommandNotification", StringComparison.InvariantCultureIgnoreCase)) { SqlDependency.Start(_connect); _2005dependency = true; } else { // If not "CommandNotification", then extract database and table names string[] info = dependency.Split(new char[] { ':' }); if (info.Length != 2) throw new ProviderException(_errmsg8); _database = info[0]; _table = info[1]; } config.Remove("sqlCacheDependency"); } // SiteMapProvider processes the securityTrimmingEnabled // attribute but fails to remove it. Remove it now so we can // check for unrecognized configuration attributes. if (config["securityTrimmingEnabled"] != null) config.Remove("securityTrimmingEnabled"); // Throw an exception if unrecognized attributes remain if (config.Count > 0) { string attr = config.GetKey(0); if (!String.IsNullOrEmpty(attr)) throw new ProviderException("Unrecognized attribute: " + attr); } } public override SiteMapNode BuildSiteMap() { lock (_lock) { // Return immediately if this method has been called before if (_root != null) return _root; // Query the database for site map nodes SqlConnection connection = new SqlConnection(_connect); try { SqlCommand command = new SqlCommand("GetSiteMap", connection); command.CommandType = CommandType.StoredProcedure; // Create a SQL cache dependency if requested SqlCacheDependency dependency = null; if (_2005dependency) dependency = new SqlCacheDependency(command); else if (!String.IsNullOrEmpty(_database) && !string.IsNullOrEmpty(_table)) dependency = new SqlCacheDependency(_database, _table); connection.Open(); 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"); //_indexImageUrl = reader.GetOrdinal("ImageUrl"); if (reader.Read()) { // Create the root SiteMapNode and add it to the site map _root = CreateSiteMapNodeFromDataReader(reader); AddNode(_root, null); // Build a tree of SiteMapNodes underneath the root node while (reader.Read()) { // Create another site map node and add it to the site map SiteMapNode node = CreateSiteMapNodeFromDataReader(reader); AddNode(node, GetParentNodeFromDataReader(reader)); } // Use the SQL cache dependency if (dependency != null) { HttpRuntime.Cache.Insert(_cacheDependencyName, new object(), dependency, Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, CacheItemPriority.NotRemovable, new CacheItemRemovedCallback(OnSiteMapChanged)); } } } finally { connection.Close(); } // Return the root SiteMapNode return _root; } } protected override SiteMapNode GetRootNodeCore () { lock (_lock) { BuildSiteMap(); return _root; } } // Helper methods private SiteMapNode CreateSiteMapNodeFromDataReader (DbDataReader reader) { // Make sure the node ID is present if (reader.IsDBNull (_indexID)) throw new ProviderException (_errmsg1); // Get the node ID from the DataReader int id = reader.GetInt32 (_indexID); // Make sure the node ID is unique if (_nodes.ContainsKey(id)) throw new ProviderException(_errmsg2); // Get title, URL, description, and roles from the DataReader 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 imageurl = reader.IsDBNull(_indexImageUrl) ? null : reader.GetString(_indexImageUrl).Trim(); // If roles were specified, turn the list into a string array string[] rolelist = null; if (!String.IsNullOrEmpty(roles)) rolelist = roles.Split(new char[] { ',', ';' }, 512); // Create a SiteMapNode SiteMapNode node = new SiteMapNode(this, id.ToString(), url, title, description, rolelist, null, null, null); // Record the node in the _nodes dictionary _nodes.Add(id, node); // Return the node return node; } private SiteMapNode GetParentNodeFromDataReader(DbDataReader reader) { // Make sure the parent ID is present if (reader.IsDBNull (_indexParent)) throw new ProviderException (_errmsg3); // Get the parent ID from the DataReader int pid = reader.GetInt32(_indexParent); // Make sure the parent ID is valid if (!_nodes.ContainsKey(pid)) throw new ProviderException(_errmsg4); // Return the parent SiteMapNode return _nodes[pid]; } void OnSiteMapChanged(string key, object item, CacheItemRemovedReason reason) { lock (_lock) { if (key == _cacheDependencyName && reason == CacheItemRemovedReason.DependencyChanged) { // Refresh the site map Clear (); _nodes.Clear(); _root = null; } } }}I tried modifying the following lines in the class file in a vain attempt to add my custom attribute 'ImageUrl', but it's not working. I've commented out the parts I tried to add. private int _indexID, _indexTitle, _indexUrl, _indexDesc, _indexRoles, _indexParent; //, _indexImageUrl; //_indexImageUrl = reader.GetOrdinal("ImageUrl"); //string imageurl = reader.IsDBNull(_indexImageUrl) ? null : reader.GetString(_indexImageUrl).Trim();I haven't been able to figure out how to properly modify the class file so I can include custom attributes?Any help is appreciated.Thank you. |
|