Created
March 27, 2013 23:55
-
-
Save moaschterle/5259268 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Configuration.Provider; | |
using System.Collections; | |
using System.Collections.Specialized; | |
using System.IO; | |
using System.Security.Permissions; | |
using System.Web; | |
using System.Linq; | |
using System.Web.Caching; | |
using System.Configuration; | |
namespace DynamicSitemap | |
{ | |
[AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Minimal)] | |
public class SimpleTextSiteMapProvider : SiteMapProvider | |
{ | |
private SiteMapProvider parentSiteMapProvider = null; | |
private string simpleTextProviderName = null; | |
private string sourceFilename = null; | |
private SiteMapNode rootNode = null; | |
private ArrayList siteMapNodes = null; | |
private ArrayList childParentRelationship = null; | |
// A default constructor. The Name property is initialized in the | |
// Initialize method. | |
public SimpleTextSiteMapProvider() | |
{ | |
} | |
// Implement the CurrentNode property. | |
public override SiteMapNode CurrentNode | |
{ | |
get | |
{ | |
string currentUrl = FindCurrentUrl(); | |
// Find the SiteMapNode that represents the current page. | |
SiteMapNode currentNode = FindSiteMapNode(currentUrl); | |
return currentNode; | |
} | |
} | |
// Implement the RootNode property. | |
public override SiteMapNode RootNode | |
{ | |
get | |
{ | |
return rootNode; | |
} | |
} | |
// Implement the ParentProvider property. | |
public override SiteMapProvider ParentProvider | |
{ | |
get | |
{ | |
return parentSiteMapProvider; | |
} | |
set | |
{ | |
parentSiteMapProvider = value; | |
} | |
} | |
// Implement the RootProvider property. | |
public override SiteMapProvider RootProvider | |
{ | |
get | |
{ | |
// If the current instance belongs to a provider hierarchy, it | |
// cannot be the RootProvider. Rely on the ParentProvider. | |
if (this.ParentProvider != null) | |
{ | |
return ParentProvider.RootProvider; | |
} | |
// If the current instance does not have a ParentProvider, it is | |
// not a child in a hierarchy, and can be the RootProvider. | |
else | |
{ | |
return this; | |
} | |
} | |
} | |
// Implement the FindSiteMapNode method. | |
public override SiteMapNode FindSiteMapNode(string rawUrl) | |
{ | |
// Does the root node match the URL? | |
if (RootNode.Url == rawUrl) | |
{ | |
return RootNode; | |
} | |
else | |
{ | |
SiteMapNode candidate = null; | |
// Retrieve the SiteMapNode that matches the URL. | |
lock (this) | |
{ | |
candidate = GetNode(siteMapNodes, rawUrl); | |
} | |
return candidate; | |
} | |
} | |
// Implement the GetChildNodes method. | |
public override SiteMapNodeCollection GetChildNodes(SiteMapNode node) | |
{ | |
SiteMapNodeCollection children = new SiteMapNodeCollection(); | |
// Iterate through the ArrayList and find all nodes that have the specified node as a parent. | |
lock (this) | |
{ | |
for (int i = 0; i < childParentRelationship.Count; i++) | |
{ | |
string nodeUrl = ((DictionaryEntry)childParentRelationship[i]).Key as string; | |
SiteMapNode parent = GetNode(childParentRelationship, nodeUrl); | |
if (parent != null && node.Url == parent.Url) | |
{ | |
// The SiteMapNode with the Url that corresponds to nodeUrl | |
// is a child of the specified node. Get the SiteMapNode for | |
// the nodeUrl. | |
SiteMapNode child = FindSiteMapNode(nodeUrl); | |
if (child != null) | |
{ | |
children.Add(child as SiteMapNode); | |
} | |
else | |
{ | |
throw new Exception("ArrayLists not in sync."); | |
} | |
} | |
} | |
} | |
return children; | |
} | |
protected override SiteMapNode GetRootNodeCore() | |
{ | |
return RootNode; | |
} | |
// Implement the GetParentNode method. | |
public override SiteMapNode GetParentNode(SiteMapNode node) | |
{ | |
// Check the childParentRelationship table and find the parent of the current node. | |
// If there is no parent, the current node is the RootNode. | |
SiteMapNode parent = null; | |
lock (this) | |
{ | |
// Get the Value of the node in childParentRelationship | |
parent = GetNode(childParentRelationship, node.Url); | |
} | |
return parent; | |
} | |
// Implement the ProviderBase.Initialize property. | |
// Initialize is used to initialize the state that the Provider holds, but | |
// not actually build the site map. | |
public override void Initialize(string name, NameValueCollection attributes) | |
{ | |
lock (this) | |
{ | |
base.Initialize(name, attributes); | |
simpleTextProviderName = name; | |
//sourceFilename = attributes["siteMapFile"]; | |
siteMapNodes = new ArrayList(); | |
childParentRelationship = new ArrayList(); | |
// Build the site map in memory. | |
LoadSiteMapFromStore(); | |
} | |
} | |
// Private helper methods | |
private SiteMapNode GetNode(ArrayList list, string url) | |
{ | |
for (int i = 0; i < list.Count; i++) | |
{ | |
DictionaryEntry item = (DictionaryEntry)list[i]; | |
if ((string)item.Key == url) | |
return item.Value as SiteMapNode; | |
} | |
return null; | |
} | |
// Get the URL of the currently displayed page. | |
private string FindCurrentUrl() | |
{ | |
try | |
{ | |
// The current HttpContext. | |
HttpContext currentContext = HttpContext.Current; | |
if (currentContext != null) | |
{ | |
return currentContext.Request.RawUrl; | |
} | |
else | |
{ | |
throw new Exception("HttpContext.Current is Invalid"); | |
} | |
} | |
catch (Exception e) | |
{ | |
throw new NotSupportedException("This provider requires a valid context.", e); | |
} | |
} | |
protected virtual SiteMapNode LoadSiteMapFromStore() | |
{ | |
lock (this) | |
{ | |
if (HttpRuntime.Cache[CacheKey()] == null) | |
{ | |
//// If a root node exists, LoadSiteMapFromStore has already | |
//// been called, and the method can return. | |
//if (rootNode != null) | |
//{ | |
// return; | |
//} | |
//else | |
//{ | |
// Clear the state of the collections and rootNode | |
rootNode = null; | |
siteMapNodes.Clear(); | |
childParentRelationship.Clear(); | |
// Parse the file and build the site map | |
SiteMapNode temp = null; | |
using (MyDBContainer db = new MyDBContainer()) | |
{ | |
var formsmenu = (from xy in db.FormsSet orderby xy.Level select xy); | |
foreach (Forms myform in formsmenu) | |
{ | |
// Build the various SiteMapNode objects and add | |
// them to the ArrayList collections. The format used | |
// is: URL,TITLE,DESCRIPTION,PARENTURL | |
temp = new SiteMapNode(this, myform.UrlDE, myform.UrlDE, myform.TitleDE, myform.TitleDE); | |
//HttpRuntime.AppDomainAppVirtualPath + "/" + nodeValues[0], | |
//HttpRuntime.AppDomainAppVirtualPath + "/" + nodeValues[0], | |
//nodeValues[1], | |
//nodeValues[2]); | |
// Is this a root node yet? | |
if (null == rootNode && (myform.Level == 0)) | |
{ | |
rootNode = temp; | |
} | |
// If not the root node, add the node to the various collections. | |
else | |
{ | |
var parentnode = (from xy in db.FormsSet where xy.Id == myform.ParentID select xy).FirstOrDefault(); | |
siteMapNodes.Add(new DictionaryEntry(temp.Url, temp)); | |
// The parent node has already been added to the collection. | |
SiteMapNode parentNode = | |
FindSiteMapNode(parentnode.UrlDE); | |
if (parentNode != null) | |
{ | |
childParentRelationship.Add(new DictionaryEntry(temp.Url, parentNode)); | |
} | |
else | |
{ | |
throw new Exception("Parent node not found for current node."); | |
} | |
} | |
} | |
} | |
HttpRuntime.Cache.Insert(CacheKey(), rootNode, new CacheDependency(HttpContext.Current.Server.MapPath(ConfigurationManager.AppSettings["CachingCategoryDependency"])), | |
Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, CacheItemPriority.NotRemovable, new CacheItemRemovedCallback(OnSiteMapChanged)); | |
return rootNode; | |
} | |
else | |
{ | |
//HttpContext.Current.Trace.Warn("BuildSiteMap", "CACHED"); | |
return (SiteMapNode)HttpRuntime.Cache[CacheKey()]; | |
} | |
} | |
//return; | |
} | |
void OnSiteMapChanged(string key, object item, CacheItemRemovedReason reason) | |
{ | |
lock (this) | |
{ | |
if (reason == CacheItemRemovedReason.DependencyChanged) | |
{ | |
HttpRuntime.Cache.Remove(CacheKey()); | |
LoadSiteMapFromStore(); | |
} | |
} | |
} | |
public static string CacheKey() | |
{ | |
// Hier die Logik für den Cache-Key implementieren. | |
// Z.B. jeweils für die ID der obersten Kategorie, wenn diese bsp. als | |
// Sprache deklariert wird. | |
//int highestID = 0; | |
//using (MyDBContainer db = new MyDBContainer()) | |
//{ | |
// highestID = (from xy in db.FormsSet select xy).Max(x => x.Id); | |
//} | |
return "mischt"; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment