}/* LogIt("In the cache all section : session says " + (System.Web.HttpContext.Current.Application["customUrlCacheActivated"] == null ? "No setting" : "Setting Found") + " : requestedUrl.Path = " + requestedUrl.Path + " : _webContext.Url.Path = " + _webContext.Url.Path + " : isFile? = " + isFile(_webContext.Url.Path)); */ public PathData ResolvePath(string url) { Url requestedUrl = url; //look for files etc and ignore bool bNeedsProcessing = true; if (requestedUrl.Path.ToLower().StartsWith("/assets/")) bNeedsProcessing = false; else if (!requestedUrl.Path.StartsWith("/")) bNeedsProcessing = false; else if (isFile(requestedUrl.Path, false)) bNeedsProcessing = false; if (!bNeedsProcessing) { PathData data = new PathData(); data.IsRewritable = false; return data; } else { ContentItem item = TryLoadingFromQueryString(requestedUrl, PathData.PageQueryKey); if (item != null) return item.FindPath(requestedUrl["action"] ?? PathData.DefaultAction) .SetArguments(requestedUrl["arguments"]) .UpdateParameters(requestedUrl.GetQueries()); ContentItem startPage = GetStartPage(requestedUrl); string languageCode = GetLanguage(ref requestedUrl); string path = Url.ToRelative(requestedUrl.Path).TrimStart('~'); PathData data = startPage.FindPath(path, languageCode).UpdateParameters(requestedUrl.GetQueries()); if (data.IsEmpty()) { if (path.EndsWith(DefaultDocument, StringComparison.OrdinalIgnoreCase)) { // Try to find path without default document. data = StartPage .FindPath(path.Substring(0, path.Length - DefaultDocument.Length)) .UpdateParameters(requestedUrl.GetQueries()); } //cache data first time we go through this if ((_configUrlsSection.ParentIDs.Count > 0) && (System.Web.HttpContext.Current.Application["customUrlCacheActivated"] == null)) { //the below takes resource and time, we only want one request doing this at a time, so set the flag immediately System.Web.HttpContext.Current.Application["customUrlCacheActivated"] = "true"; System.Web.HttpContext.Current.Application["customUrlCacheInitialLoopLastRun"] = System.DateTime.Now; foreach (CustomUrlsIDElement id in _configUrlsSection.ParentIDs) { // First check that the page referenced in web.config actually exists. ContentItem customUrlPage = Persister.Get(id.ID); if (customUrlPage == null) continue; //need to check all children of these nodes to see if there's a match IEnumerable<ContentItem> AllContentItemsWithCustomUrls = Find.EnumerateAccessibleChildren(customUrlPage, id.Depth); foreach (ContentItem ci in AllContentItemsWithCustomUrls) { if (ci.HasCustomUrl) { System.Web.HttpContext.Current.Application["customUrlCache_" + ci.Url] = ci.ID; System.Web.HttpContext.Current.Application["customUrlCacheAction_" + ci.Url] = ""; } } } System.Web.HttpContext.Current.Application["customUrlCacheInitialLoopComplete"] = System.DateTime.Now; } bool bTryCustomUrls = false; { if (!isFile(requestedUrl.Path, true)) { foreach (CustomUrlsMandatoryStringsElement stringToFind in _configUrlsSection.MandatoryStrings) { if (_webContext.Url.Path.IndexOf(stringToFind.Value) > -1) { bTryCustomUrls = true; break; } } } } if (data.IsEmpty() && requestedUrl.Path.IndexOf(".") == -1 && bTryCustomUrls) { DateTime lastRun = Convert.ToDateTime(System.Web.HttpContext.Current.Application["customUrlCacheInitialLoopLastRun"]); DateTime lastComplete = System.Web.HttpContext.Current.Application["customUrlCacheInitialLoopComplete"] == null ? DateTime.MinValue : Convert.ToDateTime(System.Web.HttpContext.Current.Application["customUrlCacheInitialLoopLastRun"]); //temp measure - sleep until the initial loop is complete int loops = 0; while (lastComplete < lastRun && loops < 20) { loops++; System.Threading.Thread.Sleep(1000); lastComplete = System.Web.HttpContext.Current.Application["customUrlCacheInitialLoopComplete"] == null ? DateTime.MinValue : Convert.ToDateTime(System.Web.HttpContext.Current.Application["customUrlCacheInitialLoopLastRun"]); } //this code can freak out the 2nd level caching in NHibernate, so clear it if within 5 mins of the last time the cache everything loop was called //TO DO: implement this /* if (DateTime.Now.Subtract(lastRun).TotalMinutes < 5) { NHibernate.Cfg.Configuration Configuration = new NHibernate.Cfg.Configuration(); ISessionFactory sessionFactory = Configuration.BuildSessionFactory(); sessionFactory.EvictQueries(); foreach (var collectionMetadata in sessionFactory.GetAllCollectionMetadata()) sessionFactory.EvictCollection(collectionMetadata.Key); foreach (var classMetadata in sessionFactory.GetAllClassMetadata()) sessionFactory.EvictEntity(classMetadata.Key); } */ //check cache for previously mapped item if (System.Web.HttpContext.Current.Application["customUrlCache_" + _webContext.Url.Path] == null) { //HACK!! Using the RapidCheck elements in config try to pre-empt this being a known path with the action //This needed to be implemented for performance reasons string fullPath = _webContext.Url.Path; string pathNoAction = ""; string action = ""; if (fullPath.LastIndexOf("/") > -1) { pathNoAction = fullPath.Substring(0, fullPath.LastIndexOf("/")); action = fullPath.Substring(fullPath.LastIndexOf("/") + 1); } foreach (CustomUrlsRapidCheckElement possibleAction in _configUrlsSection.RapidCheck) { if (possibleAction.Action == action) { //check for cache //see whether we have the root item in the cache... if (System.Web.HttpContext.Current.Application["customUrlCache_" + pathNoAction] != null) { //we now have a match without any more calls to the database ContentItem ci = _persister.Get((int)System.Web.HttpContext.Current.Application["customUrlCache_" + pathNoAction]); data = ci.FindPath(action); System.Web.HttpContext.Current.Application["customUrlCache_" + _webContext.Url.Path] = ci.ID; System.Web.HttpContext.Current.Application["customUrlCacheAction_" + _webContext.Url.Path] = action; return data; } } } // Check for Custom Urls (could be done in a service that subscribes to the IUrlParser.PageNotFound event)... foreach (CustomUrlsIDElement id in _configUrlsSection.ParentIDs) { // First check that the page referenced in web.config actually exists. ContentItem customUrlPage = Persister.Get(id.ID); if (customUrlPage == null) continue; //need to check all children of these nodes to see if there's a match ContentItem tryMatch = Find.EnumerateAccessibleChildren(customUrlPage, id.Depth).SingleOrDefault( ci => ci.Url.Equals(_webContext.Url.Path, StringComparison.InvariantCultureIgnoreCase)); if (tryMatch != null) { data = tryMatch.FindPath(PathData.DefaultAction); System.Web.HttpContext.Current.Application["customUrlCache_" + _webContext.Url.Path] = tryMatch.ID; System.Web.HttpContext.Current.Application["customUrlCacheAction_" + _webContext.Url.Path] = ""; break; } //now need to check for an action... if (fullPath.LastIndexOf("/") > -1) { //see whether we have the root item in the cache... if (System.Web.HttpContext.Current.Application["customUrlCache_" + pathNoAction] == null) { ContentItem tryMatchAgain = Find.EnumerateAccessibleChildren(Persister.Get(id.ID), id.Depth).SingleOrDefault( ci => ci.Url.Equals(pathNoAction, StringComparison.InvariantCultureIgnoreCase)); if (tryMatchAgain != null) { data = tryMatchAgain.FindPath(action); System.Web.HttpContext.Current.Application["customUrlCache_" + _webContext.Url.Path] = tryMatchAgain.ID; System.Web.HttpContext.Current.Application["customUrlCacheAction_" + _webContext.Url.Path] = action; break; } } else { ContentItem ci = _persister.Get((int)System.Web.HttpContext.Current.Application["customUrlCache_" + pathNoAction]); data = ci.FindPath(action); System.Web.HttpContext.Current.Application["customUrlCache_" + _webContext.Url.Path] = ci.ID; System.Web.HttpContext.Current.Application["customUrlCacheAction_" + _webContext.Url.Path] = action; break; } } } } else { ContentItem ci = _persister.Get((int)System.Web.HttpContext.Current.Application["customUrlCache_" + _webContext.Url.Path]); string act = System.Web.HttpContext.Current.Application["customUrlCacheAction_" + _webContext.Url.Path].ToString(); if (string.IsNullOrEmpty(act)) return ci.FindPath(PathData.DefaultAction); else return ci.FindPath(act); } } if (data.IsEmpty()) { // Allow user code to set path through event if (PageNotFound != null) { PageNotFoundEventArgs args = new PageNotFoundEventArgs(requestedUrl); args.AffectedPath = data; PageNotFound(this, args); if (args.AffectedItem != null) data = args.AffectedItem.FindPath(PathData.DefaultAction); else data = args.AffectedPath; } } } data.IsRewritable = IsRewritable(_webContext.PhysicalPath); return data; } }
private void OnUrlParserPageNotFound(object sender, PageNotFoundEventArgs e) { WebsiteNode websiteNode = _urlParser.StartPage as WebsiteNode; if (websiteNode != null && websiteNode.PageNotFoundPage != null && !e.Url.StartsWith(_adminConfig.Path + "/", StringComparison.InvariantCultureIgnoreCase)) e.AffectedItem = websiteNode.PageNotFoundPage; }
protected virtual ContentItem NotFoundPage(string url) { if (url.Equals(DefaultDocument, StringComparison.InvariantCultureIgnoreCase)) return StartPage; PageNotFoundEventArgs args = new PageNotFoundEventArgs(url); if (PageNotFound != null) PageNotFound(this, args); return args.AffectedItem; }