|
Posted on
2009-04-15 21:46
Brian Wang
阅读( 570)
评论()
编辑
收藏
举报
The sitemap provider of .NET 2.0 is great but what if you have database generated pages ?
1 way to do it is to create a table in your database that has the same structure as the web.sitemap. And write your own custom sitemap provider.
Jef Prosise wrote an article about this in the wicked code magazine from Microsoft.
http://msdn.microsoft.com/msdnmag/issues/05/06/WickedCode/
This is all cool and nice but still I would be inputting a lot of code and every time when a database entry would change I would have to change it manually in my sitemap table.
I want to get everything directly from my different tables. The code that I provide below is not the fastest available but it is for a small application so I can’t care less. Instead of the SqlDataSource I could have used the sqlcommand and datareader to get the info out of my database which would make it faster.
Seen as it looked fairly simple to write my own sitemap provider I got to work and about 2 hours later it was all done. I left the roles in there but for the moment the app is not using roles so I just bypass it by setting it default to “*“.
Jeff uses a dictionary to look for duplicate keys. This didn’t work so good for me but I let it be there anyway.
It comes down to it that you inherit your class from the StaticSiteMapProvider and you implement the class in your document. For comments in the code please check jeff’s article he does it prettey good ;)
The Sitemapprovider :
Code using System; using System.Data; using System.Configuration; using System.Web; using System.Web.Security; using System.Collections.Specialized; using System.Collections.Generic; using System.Runtime.CompilerServices; using System.Web.UI.WebControls; using System.Web.UI;
public class MySitemapProvider:StaticSiteMapProvider { private SqlDataSource sds = new SqlDataSource(); static readonly string _errmsg1 = "Missing connectionStringName attribute"; static readonly string _errmsg2 = "Duplicate node ID"; SiteMapNode _root = null; string _connect;
public override void Initialize(string name, NameValueCollection attributes) { base.Initialize(name, attributes);
if (attributes == null) throw new ConfigurationErrorsException(_errmsg1);
_connect = attributes["connectionStringName"]; sds.ConnectionString = ConfigurationManager.ConnectionStrings[_connect].ConnectionString; if (String.IsNullOrEmpty(_connect)) throw new ConfigurationErrorsException(_errmsg1); }
public override SiteMapNode BuildSiteMap() { if (_root != null) return _root;
Dictionary<Guid,SiteMapNode> nodes = new Dictionary<Guid,SiteMapNode>(); Guid id = Guid.NewGuid(); string[] roles = new string[]{"*"}; _root = new SiteMapNode(this, id.ToString(), "~/Default.aspx?home", "Home", "RTD Home page"); _root.Roles = roles;
if (nodes.ContainsKey(id)) throw new ConfigurationErrorsException(_errmsg2);
nodes.Add(id, _root); AddNode(_root, null); CreateNode(_root, nodes, Guid.NewGuid(), "Home", "RTD Home page", "~/Default.aspx", roles); Guid whoID = Guid.NewGuid(); SiteMapNode who = CreateNode(_root, nodes, whoID, "Who we are", "General information about our company", "", roles); GetPageNames(who, nodes, roles); Guid whatID = Guid.NewGuid(); SiteMapNode what = CreateNode(_root, nodes, whatID, "What we do", "Services that we provide", "", roles); GetServiceNames(what, nodes, roles); CreateNode(_root, nodes, Guid.NewGuid(), "News", "Company news", "~/News.aspx", roles); CreateNode(_root, nodes, Guid.NewGuid(), "Contact Us", "Our contact information", "~/ContactUs.aspx", roles); CreateNode(_root, nodes, Guid.NewGuid(), "Help", "Get help for this site", "~/Help.aspx", roles); CreateNode(_root, nodes, Guid.NewGuid(), "Sitemap", "Sitemap", "~/Sitemap.aspx", roles); return _root; } private void GetPageNames(SiteMapNode parent,Dictionary<Guid,SiteMapNode> nodes, string[] roles) { sds.SelectCommand = "sp_SelPage"; sds.SelectCommandType = SqlDataSourceCommandType.StoredProcedure; sds.SelectParameters.Add(new Parameter("Page_Deleted", TypeCode.Boolean, "false")); DataView dv = (DataView)sds.Select(DataSourceSelectArguments.Empty); foreach (DataRowView drv in dv) { CreateNode(parent,nodes,(Guid)drv["Page_GUID"], drv["Page_Name"].ToString(), drv["Page_Name"].ToString(), "~/Page.aspx?s=" + drv["Page_GUID"].ToString(),roles); } } private void GetServiceNames(SiteMapNode parent, Dictionary<Guid, SiteMapNode> nodes, string[] roles) { sds.SelectCommand = "sp_SelDistinctCategoryService"; sds.SelectCommandType = SqlDataSourceCommandType.StoredProcedure; sds.SelectParameters.Clear(); DataView dvCat = (DataView)sds.Select(DataSourceSelectArguments.Empty); foreach (DataRowView drvCat in dvCat) { Guid id = (Guid)drvCat["Category_GUID"]; SiteMapNode cat = new SiteMapNode(this, id.ToString()); cat.Title = drvCat["Category_Name"].ToString(); cat.Description = drvCat["Category_Name"].ToString(); cat.Roles = roles; nodes.Add(id, cat); AddNode(cat, parent); sds.SelectCommand = "sp_SelSubcategoryService"; sds.SelectCommandType = SqlDataSourceCommandType.StoredProcedure; sds.SelectParameters.Clear(); sds.SelectParameters.Add(new Parameter("Service_Category", TypeCode.Int32, drvCat["Service_Category"].ToString())); DataView dvSub = (DataView)sds.Select(DataSourceSelectArguments.Empty); foreach (DataRowView drvSub in dvSub) { Guid Sid = (Guid)drvSub["Subcategory_GUID"]; SiteMapNode Scat = new SiteMapNode(this, Sid.ToString()); Scat.Title = drvSub["Subcategory_Name"].ToString(); Scat.Description = drvSub["Subcategory_Name"].ToString(); Scat.Roles=roles; nodes.Add(Sid, Scat); AddNode(Scat, cat); sds.SelectCommand = "sp_SelServiceByCategory"; sds.SelectCommandType = SqlDataSourceCommandType.StoredProcedure; sds.SelectParameters.Clear(); sds.SelectParameters.Add(new Parameter("Service_Category", TypeCode.Int32, drvSub["Service_Subcategory"].ToString))); DataView dv = (DataView)sds.Select(DataSourceSelectArguments.Empty); foreach (DataRowView drv in dv) { CreateNode(Scat, nodes, (Guid)drv["Service_GUID"], drv["Service_Name"].ToString(), drv["Service_Name"].ToString(), "~/Services.aspx?s=" + drv["Service_GUID"].ToString(), roles); } } } } private SiteMapNode CreateNode(SiteMapNode parent,Dictionary<Guid,SiteMapNode> nodes, Guid id, string title, string desc, string url, string[] roles) { SiteMapNode node = new SiteMapNode(this, id.ToString(), url, title, desc); node.Roles = roles; if (nodes.ContainsKey(id)) throw new ConfigurationErrorsException(_errmsg2); nodes.Add(id, node); AddNode(node, parent); return node; } protected override SiteMapNode GetRootNodeCore() { BuildSiteMap(); return _root; }
The web.config :
In the system.web add :
<siteMap defaultProvider="MySiteMapProvider" enabled="true">
<providers>
<clear />
<add name="MySiteMapProvider" type="MySitemapProvider" securityTrimmingEnabled="true" connectionStringName="RTDConnectionString" />
</providers>
</siteMap>
|