diff --git a/src/Umbraco.Web/Routing/ContentFinderByLegacy404.cs b/src/Umbraco.Web/Routing/ContentFinderByLegacy404.cs
index c092668ea3..660c88e979 100644
--- a/src/Umbraco.Web/Routing/ContentFinderByLegacy404.cs
+++ b/src/Umbraco.Web/Routing/ContentFinderByLegacy404.cs
@@ -7,15 +7,11 @@ using Umbraco.Core;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
-using umbraco;
-using umbraco.interfaces;
-
namespace Umbraco.Web.Routing
{
///
/// Provides an implementation of that runs the legacy 404 logic.
///
- /// Should be used as a last chance finder.
internal class ContentFinderByLegacy404 : IContentFinder
{
///
@@ -25,8 +21,9 @@ namespace Umbraco.Web.Routing
/// A value indicating whether an Umbraco document was found and assigned.
public bool TryFindDocument(PublishedContentRequest pcr)
{
- LogHelper.Debug("Looking for a page to handler 404.");
+ LogHelper.Debug("Looking for a page to handle 404.");
+ // TODO - replace the whole logic and stop calling into library!
var error404 = global::umbraco.library.GetCurrentNotFoundPageId();
var id = int.Parse(error404);
@@ -51,6 +48,7 @@ namespace Umbraco.Web.Routing
}
pcr.PublishedContent = content;
+ pcr.SetIs404();
return content != null;
}
}
diff --git a/src/Umbraco.Web/Routing/ContentFinderByNotFoundHandlers.cs b/src/Umbraco.Web/Routing/ContentFinderByNotFoundHandlers.cs
index f46f393135..0824918dee 100644
--- a/src/Umbraco.Web/Routing/ContentFinderByNotFoundHandlers.cs
+++ b/src/Umbraco.Web/Routing/ContentFinderByNotFoundHandlers.cs
@@ -21,9 +21,6 @@ namespace Umbraco.Web.Routing
// at the moment we load the legacy INotFoundHandler
// excluding those that have been replaced by proper finders,
// and run them.
- //
- // code from requestHandler.handle404 has been moved over to
- // the new ContentFinderByLegacy404 finder.
///
/// Tries to find and assign an Umbraco document to a PublishedContentRequest.
@@ -32,34 +29,71 @@ namespace Umbraco.Web.Routing
/// A value indicating whether an Umbraco document was found and assigned.
public bool TryFindDocument(PublishedContentRequest docRequest)
{
- docRequest.PublishedContent = HandlePageNotFound(docRequest);
+ HandlePageNotFound(docRequest);
return docRequest.HasPublishedContent;
}
- #region Copied over from presentation.requestHandler
+ #region Copied over and adapted from presentation.requestHandler
//FIXME: this is temporary and should be obsoleted
- IPublishedContent HandlePageNotFound(PublishedContentRequest docRequest)
+ void HandlePageNotFound(PublishedContentRequest docRequest)
{
LogHelper.Debug("Running for url='{0}'.", () => docRequest.Uri.AbsolutePath);
- //XmlNode currentPage = null;
- IPublishedContent currentPage = null;
var url = NotFoundHandlerHelper.GetLegacyUrlForNotFoundHandlers();
foreach (var handler in GetNotFoundHandlers())
{
+ IContentFinder finder = null;
+
+ LogHelper.Debug("Handler '{0}'.", () => handler.GetType().FullName);
+
+ // replace with our own implementation
+ if (handler is global::umbraco.SearchForAlias)
+ finder = new ContentFinderByUrlAlias();
+ else if (handler is global::umbraco.SearchForProfile)
+ finder = new ContentFinderByProfile();
+ else if (handler is global::umbraco.SearchForTemplate)
+ finder = new ContentFinderByNiceUrlAndTemplate();
+ else if (handler is global::umbraco.handle404)
+ finder = new ContentFinderByLegacy404();
+
+ if (finder != null)
+ {
+ LogHelper.Debug("Replace handler '{0}' by new finder '{1}'.", () => handler.GetType().FullName, () => finder.GetType().FullName);
+ if (finder.TryFindDocument(docRequest))
+ {
+ // do NOT set docRequest.PublishedContent again here as
+ // it would clear any template that the finder might have set
+ LogHelper.Debug("Finder '{0}' found node with id={1}.", () => finder.GetType().FullName, () => docRequest.PublishedContent.Id);
+ if (docRequest.Is404)
+ LogHelper.Debug("Finder '{0}' set status to 404.", () => finder.GetType().FullName);
+ return;
+ }
+ }
+
+ // else it's a legacy handler, run
+
if (handler.Execute(url) && handler.redirectID > 0)
{
- //currentPage = umbracoContent.GetElementById(handler.redirectID.ToString());
- currentPage = docRequest.RoutingContext.PublishedContentStore.GetDocumentById(
+ docRequest.PublishedContent = docRequest.RoutingContext.PublishedContentStore.GetDocumentById(
docRequest.RoutingContext.UmbracoContext,
handler.redirectID);
- // FIXME - could it be null?
+ if (!docRequest.HasPublishedContent)
+ {
+ LogHelper.Debug("Handler '{0}' found node with id={1} which is not valid.", () => handler.GetType().FullName, () => handler.redirectID);
+ break;
+ }
- LogHelper.Debug("Handler '{0}' found node with id={1}.", () => handler.GetType().FullName, () => handler.redirectID);
+ LogHelper.Debug("Handler '{0}' found valid node with id={1}.", () => handler.GetType().FullName, () => handler.redirectID);
+
+ if (docRequest.RoutingContext.UmbracoContext.HttpContext.Response.StatusCode == 404)
+ {
+ LogHelper.Debug("Handler '{0}' set status code to 404.", () => handler.GetType().FullName);
+ docRequest.Is404 = true;
+ }
//// check for caching
//if (handler.CacheUrl)
@@ -78,60 +112,6 @@ namespace Umbraco.Web.Routing
break;
}
}
-
- return currentPage;
- }
-
- static IEnumerable _customHandlerTypes = null;
- static readonly object CustomHandlerTypesLock = new object();
-
- IEnumerable InitializeNotFoundHandlers()
- {
- // initialize handlers
- // create the definition cache
-
- LogHelper.Debug("Registering custom handlers.");
-
- var customHandlerTypes = new List();
-
- var customHandlers = new XmlDocument();
- customHandlers.Load(Umbraco.Core.IO.IOHelper.MapPath(Umbraco.Core.IO.SystemFiles.NotFoundhandlersConfig));
-
- foreach (XmlNode n in customHandlers.DocumentElement.SelectNodes("notFound"))
- {
- var assemblyName = n.Attributes.GetNamedItem("assembly").Value;
-
- // skip those that are in umbraco.dll because we have replaced them with finders
- if (assemblyName == "umbraco")
- continue;
-
- var typeName = n.Attributes.GetNamedItem("type").Value;
- string ns = assemblyName;
- var nsAttr = n.Attributes.GetNamedItem("namespace");
- if (nsAttr != null && !string.IsNullOrWhiteSpace(nsAttr.Value))
- ns = nsAttr.Value;
-
- LogHelper.Debug("Registering '{0}.{1},{2}'.", () => ns, () => typeName, () => assemblyName);
-
- Type type = null;
- try
- {
- //TODO: This isn't a good way to load the assembly, its already in the Domain so we should be getting the type
- // this loads the assembly into the wrong assembly load context!!
-
- var assembly = Assembly.LoadFrom(Umbraco.Core.IO.IOHelper.MapPath(Umbraco.Core.IO.SystemDirectories.Bin + "/" + assemblyName + ".dll"));
- type = assembly.GetType(ns + "." + typeName);
- }
- catch (Exception e)
- {
- LogHelper.Error("Error registering handler, ignoring.", e);
- }
-
- if (type != null)
- customHandlerTypes.Add(type);
- }
-
- return customHandlerTypes;
}
IEnumerable GetNotFoundHandlers()
@@ -139,15 +119,9 @@ namespace Umbraco.Web.Routing
// instanciate new handlers
// using definition cache
- lock (CustomHandlerTypesLock)
- {
- if (_customHandlerTypes == null)
- _customHandlerTypes = InitializeNotFoundHandlers();
- }
-
var handlers = new List();
- foreach (var type in _customHandlerTypes)
+ foreach (var type in NotFoundHandlerHelper.CustomHandlerTypes)
{
try
{
diff --git a/src/Umbraco.Web/Routing/ContentFinderByUrlAlias.cs b/src/Umbraco.Web/Routing/ContentFinderByUrlAlias.cs
index 1442642e6f..cc0a3e6a3a 100644
--- a/src/Umbraco.Web/Routing/ContentFinderByUrlAlias.cs
+++ b/src/Umbraco.Web/Routing/ContentFinderByUrlAlias.cs
@@ -23,7 +23,6 @@ namespace Umbraco.Web.Routing
/// A value indicating whether an Umbraco document was found and assigned.
public bool TryFindDocument(PublishedContentRequest docRequest)
{
-
IPublishedContent node = null;
if (docRequest.Uri.AbsolutePath != "/") // no alias if "/"
diff --git a/src/Umbraco.Web/Routing/NotFoundHandlerHelper.cs b/src/Umbraco.Web/Routing/NotFoundHandlerHelper.cs
index 94cdb5aeaf..082e28c35a 100644
--- a/src/Umbraco.Web/Routing/NotFoundHandlerHelper.cs
+++ b/src/Umbraco.Web/Routing/NotFoundHandlerHelper.cs
@@ -3,14 +3,24 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
+using System.Xml;
+using System.Reflection;
+
+using Umbraco.Core;
+using Umbraco.Core.Logging;
namespace Umbraco.Web.Routing
{
// provides internal access to legacy url -- should get rid of it eventually
- internal static class NotFoundHandlerHelper
+ internal class NotFoundHandlerHelper
{
const string ContextKey = "Umbraco.Web.Routing.NotFoundHandlerHelper.Url";
+ static NotFoundHandlerHelper()
+ {
+ InitializeNotFoundHandlers();
+ }
+
public static string GetLegacyUrlForNotFoundHandlers()
{
// that's not backward-compatible because when requesting "/foo.aspx"
@@ -70,5 +80,60 @@ namespace Umbraco.Web.Routing
httpContext.Items[ContextKey] = tmp;
return tmp;
}
- }
+
+ static IEnumerable _customHandlerTypes = null;
+
+ static void InitializeNotFoundHandlers()
+ {
+ // initialize handlers
+ // create the definition cache
+
+ LogHelper.Debug("Registering custom handlers.");
+
+ var customHandlerTypes = new List();
+
+ var customHandlers = new XmlDocument();
+ customHandlers.Load(Umbraco.Core.IO.IOHelper.MapPath(Umbraco.Core.IO.SystemFiles.NotFoundhandlersConfig));
+
+ foreach (XmlNode n in customHandlers.DocumentElement.SelectNodes("notFound"))
+ {
+ var assemblyName = n.Attributes.GetNamedItem("assembly").Value;
+ var typeName = n.Attributes.GetNamedItem("type").Value;
+
+ string ns = assemblyName;
+ var nsAttr = n.Attributes.GetNamedItem("namespace");
+ if (nsAttr != null && !string.IsNullOrWhiteSpace(nsAttr.Value))
+ ns = nsAttr.Value;
+
+ LogHelper.Debug("Registering '{0}.{1},{2}'.", () => ns, () => typeName, () => assemblyName);
+
+ Type type = null;
+ try
+ {
+ //TODO: This isn't a good way to load the assembly, its already in the Domain so we should be getting the type
+ // this loads the assembly into the wrong assembly load context!!
+
+ var assembly = Assembly.LoadFrom(Umbraco.Core.IO.IOHelper.MapPath(Umbraco.Core.IO.SystemDirectories.Bin + "/" + assemblyName + ".dll"));
+ type = assembly.GetType(ns + "." + typeName);
+ }
+ catch (Exception e)
+ {
+ LogHelper.Error("Error registering handler, ignoring.", e);
+ }
+
+ if (type != null)
+ customHandlerTypes.Add(type);
+ }
+
+ _customHandlerTypes = customHandlerTypes;
+ }
+
+ public static IEnumerable CustomHandlerTypes
+ {
+ get
+ {
+ return _customHandlerTypes;
+ }
+ }
+ }
}
diff --git a/src/Umbraco.Web/WebBootManager.cs b/src/Umbraco.Web/WebBootManager.cs
index 1d89a71018..b8cc3a346c 100644
--- a/src/Umbraco.Web/WebBootManager.cs
+++ b/src/Umbraco.Web/WebBootManager.cs
@@ -189,7 +189,9 @@ namespace Umbraco.Web
typeof (RenderControllerFactory)
});
- ContentLastChanceFinderResolver.Current = new ContentLastChanceFinderResolver(new ContentFinderByLegacy404());
+ // the legacy 404 will run from within ContentFinderByNotFoundHandlers below
+ // so for the time being there is no last chance finder
+ ContentLastChanceFinderResolver.Current = new ContentLastChanceFinderResolver();
ContentFinderResolver.Current = new ContentFinderResolver(
//add all known resolvers in the correct order, devs can then modify this list on application startup either by binding to events
@@ -199,9 +201,11 @@ namespace Umbraco.Web
typeof (ContentFinderByPageIdQuery),
typeof (ContentFinderByNiceUrl),
typeof (ContentFinderByIdPath),
- typeof (ContentFinderByNiceUrlAndTemplate),
- typeof (ContentFinderByProfile),
- typeof (ContentFinderByUrlAlias),
+ // these will be handled by ContentFinderByNotFoundHandlers
+ // so they can be enabled/disabled even though resolvers are not public yet
+ //typeof (ContentFinderByNiceUrlAndTemplate),
+ //typeof (ContentFinderByProfile),
+ //typeof (ContentFinderByUrlAlias),
typeof (ContentFinderByNotFoundHandlers)
});