Web.Routing - backward compatibility with legacy NotFoundHandler

This commit is contained in:
Stephan
2013-01-18 14:03:11 -01:00
parent e5a20f0c1b
commit aa1ded5f1a
7 changed files with 208 additions and 53 deletions

View File

@@ -0,0 +1,57 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Umbraco.Core;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using umbraco;
using umbraco.interfaces;
namespace Umbraco.Web.Routing
{
/// <summary>
/// Provides an implementation of <see cref="IContentFinder"/> that runs the legacy 404 logic.
/// </summary>
/// <remarks>Should be used as a last chance finder.</remarks>
internal class ContentFinderByLegacy404 : IContentFinder
{
/// <summary>
/// Tries to find and assign an Umbraco document to a <c>PublishedContentRequest</c>.
/// </summary>
/// <param name="pcr">The <c>PublishedContentRequest</c>.</param>
/// <returns>A value indicating whether an Umbraco document was found and assigned.</returns>
public bool TryFindDocument(PublishedContentRequest pcr)
{
LogHelper.Debug<ContentFinderByLegacy404>("Looking for a page to handler 404.");
var error404 = global::umbraco.library.GetCurrentNotFoundPageId();
var id = int.Parse(error404);
IPublishedContent content = null;
if (id > 0)
{
LogHelper.Debug<ContentFinderByLegacy404>("Got id={1}.", () => id);
content = pcr.RoutingContext.PublishedContentStore.GetDocumentById(
pcr.RoutingContext.UmbracoContext,
id);
if (content == null)
LogHelper.Debug<ContentFinderByLegacy404>("Could not find content with that id.");
else
LogHelper.Debug<ContentFinderByLegacy404>("Found corresponding content.");
}
else
{
LogHelper.Debug<ContentFinderByLegacy404>("Got nothing.");
}
pcr.PublishedContent = content;
return content != null;
}
}
}

View File

@@ -0,0 +1,72 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Umbraco.Core;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using umbraco;
using umbraco.interfaces;
namespace Umbraco.Web.Routing
{
/// <summary>
/// Provides an implementation of <see cref="IContentFinder"/> that runs a legacy NotFoundHandler.
/// </summary>
/// <remarks>Provided for backward compatibility.</remarks>
internal class ContentFinderByNotFoundHandler<Thandler> : IContentFinder
{
/// <summary>
/// Tries to find and assign an Umbraco document to a <c>PublishedContentRequest</c>.
/// </summary>
/// <param name="pcr">The <c>PublishedContentRequest</c>.</param>
/// <returns>A value indicating whether an Umbraco document was found and assigned.</returns>
public bool TryFindDocument(PublishedContentRequest pcr)
{
var type = typeof(Thandler);
var handler = GetHandler(type);
if (handler == null)
return false;
var url = NotFoundHandlerHelper.GetLegacyUrlForNotFoundHandlers();
if (handler.Execute(url) && handler.redirectID > 0)
{
LogHelper.Debug<ContentFinderByNotFoundHandler<Thandler>>("Handler '{0}' returned id={1}.", () => type.FullName, () => handler.redirectID);
var content = pcr.RoutingContext.PublishedContentStore.GetDocumentById(
pcr.RoutingContext.UmbracoContext,
handler.redirectID);
if (content == null)
LogHelper.Debug<ContentFinderByNotFoundHandler<Thandler>>("Could not find content with that id.");
else
LogHelper.Debug<ContentFinderByNotFoundHandler<Thandler>>("Found corresponding content.");
pcr.PublishedContent = content;
return content != null;
}
else
{
LogHelper.Debug<ContentFinderByNotFoundHandler<Thandler>>("Handler '{0}' returned nothing.", () => type.FullName);
return false;
}
}
INotFoundHandler GetHandler(Type type)
{
try
{
return Activator.CreateInstance(type) as INotFoundHandler;
}
catch (Exception e)
{
LogHelper.Error<ContentFinderByNotFoundHandler<Thandler>>(string.Format("Error instanciating handler {0}, ignoring.", type.FullName), e);
return null;
}
}
}
}

View File

@@ -15,7 +15,6 @@ namespace Umbraco.Web.Routing
/// <para>This should rather be done with a rewriting rule. There would be multiple profile pages in multi-sites/multi-langs setups.
/// We keep it for backward compatility reasons.</para>
/// </remarks>
//[ResolutionWeight(40)]
internal class ContentFinderByProfile : ContentFinderByNiceUrl
{
/// <summary>

View File

@@ -47,62 +47,13 @@ namespace Umbraco.Web.Routing
//FIXME: this is temporary and should be obsoleted
string GetLegacyUrlForNotFoundHandlers(PublishedContentRequest docRequest)
{
// that's not backward-compatible because when requesting "/foo.aspx"
// 4.9 : url = "foo.aspx"
// 4.10 : url = "/foo"
//return docRequest.Uri.AbsolutePath;
// so we have to run the legacy code for url preparation :-(
// code from requestModule.UmbracoRewrite
string tmp = HttpContext.Current.Request.Path.ToLower();
// note: requestModule.UmbracoRewrite also does some confusing stuff
// with stripping &umbPage from the querystring?! ignored.
// code from requestHandler.cleanUrl
string root = Umbraco.Core.IO.SystemDirectories.Root.ToLower();
if (!string.IsNullOrEmpty(root) && tmp.StartsWith(root))
tmp = tmp.Substring(root.Length);
tmp = tmp.TrimEnd('/');
if (tmp == "/default.aspx")
tmp = string.Empty;
else if (tmp == root)
tmp = string.Empty;
// code from UmbracoDefault.Page_PreInit
if (tmp != "" && HttpContext.Current.Request["umbPageID"] == null)
{
string tryIntParse = tmp.Replace("/", "").Replace(".aspx", string.Empty);
int result;
if (int.TryParse(tryIntParse, out result))
tmp = tmp.Replace(".aspx", string.Empty);
}
else if (!string.IsNullOrEmpty(HttpContext.Current.Request["umbPageID"]))
{
int result;
if (int.TryParse(HttpContext.Current.Request["umbPageID"], out result))
{
tmp = HttpContext.Current.Request["umbPageID"];
}
}
// code from requestHandler.ctor
if (tmp != "")
tmp = tmp.Substring(1);
return tmp;
}
IPublishedContent HandlePageNotFound(PublishedContentRequest docRequest)
{
LogHelper.Debug<ContentLastChanceFinder>("Running for url='{0}'.", () => docRequest.Uri.AbsolutePath);
//XmlNode currentPage = null;
IPublishedContent currentPage = null;
var url = GetLegacyUrlForNotFoundHandlers(docRequest);
var url = NotFoundHandlerHelper.GetLegacyUrlForNotFoundHandlers();
foreach (var handler in GetNotFoundHandlers())
{
@@ -165,7 +116,7 @@ namespace Umbraco.Web.Routing
if (assemblyName == "umbraco" && (ns + "." + typeName) != "umbraco.handle404")
{
// skip those that are in umbraco.dll because we have replaced them with IDocumentLookups
// skip those that are in umbraco.dll because we have replaced them with IContentFinder
// but do not skip "handle404" as that's the built-in legacy final handler, and for the time
// being people will have it in their config.
continue;

View File

@@ -11,6 +11,6 @@ namespace Umbraco.Web.Routing
/// <param name="docRequest">The <c>PublishedContentRequest</c>.</param>
/// <returns>A value indicating whether an Umbraco document was found and assigned.</returns>
/// <remarks>Optionally, can also assign the template or anything else on the document request, although that is not required.</remarks>
bool TryFindDocument(PublishedContentRequest docRequest);
bool TryFindDocument(PublishedContentRequest contentRequest);
}
}

View File

@@ -0,0 +1,73 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
namespace Umbraco.Web.Routing
{
// provides internal access to legacy url -- should get rid of it eventually
internal static class NotFoundHandlerHelper
{
const string ContextKey = "Umbraco.Web.Routing.NotFoundHandlerHelper.Url";
public static string GetLegacyUrlForNotFoundHandlers()
{
// that's not backward-compatible because when requesting "/foo.aspx"
// 4.9 : url = "foo.aspx"
// 4.10 : url = "/foo"
//return pcr.Uri.AbsolutePath;
// so we have to run the legacy code for url preparation :-(
var httpContext = HttpContext.Current;
if (httpContext == null)
return "";
var url = httpContext.Items[ContextKey] as string;
if (url != null)
return url;
// code from requestModule.UmbracoRewrite
string tmp = httpContext.Request.Path.ToLower();
// note: requestModule.UmbracoRewrite also does some confusing stuff
// with stripping &umbPage from the querystring?! ignored.
// code from requestHandler.cleanUrl
string root = Umbraco.Core.IO.SystemDirectories.Root.ToLower();
if (!string.IsNullOrEmpty(root) && tmp.StartsWith(root))
tmp = tmp.Substring(root.Length);
tmp = tmp.TrimEnd('/');
if (tmp == "/default.aspx")
tmp = string.Empty;
else if (tmp == root)
tmp = string.Empty;
// code from UmbracoDefault.Page_PreInit
if (tmp != "" && httpContext.Request["umbPageID"] == null)
{
string tryIntParse = tmp.Replace("/", "").Replace(".aspx", string.Empty);
int result;
if (int.TryParse(tryIntParse, out result))
tmp = tmp.Replace(".aspx", string.Empty);
}
else if (!string.IsNullOrEmpty(httpContext.Request["umbPageID"]))
{
int result;
if (int.TryParse(httpContext.Request["umbPageID"], out result))
{
tmp = httpContext.Request["umbPageID"];
}
}
// code from requestHandler.ctor
if (tmp != "")
tmp = tmp.Substring(1);
httpContext.Items[ContextKey] = tmp;
return tmp;
}
}
}

View File

@@ -325,8 +325,11 @@
<Compile Include="RenderFieldCaseType.cs" />
<Compile Include="RenderFieldEncodingType.cs" />
<Compile Include="RouteCollectionExtensions.cs" />
<Compile Include="Routing\ContentFinderByLegacy404.cs" />
<Compile Include="Routing\ContentFinderByNotFoundHandler.cs" />
<Compile Include="Routing\ContentFinderByPageIdQuery.cs" />
<Compile Include="Mvc\SurfaceControllerResolver.cs" />
<Compile Include="Routing\NotFoundHandlerHelper.cs" />
<Compile Include="Routing\PublishedContentRequestEngine.cs" />
<Compile Include="Search\ExamineEvents.cs" />
<Compile Include="Strategies\DataTypes\LegacyUploadFieldWorkaround.cs" />