diff --git a/src/Umbraco.Compat7/Web/Routing/ContentLastChangeFinderResolver.cs b/src/Umbraco.Compat7/Web/Routing/ContentLastChangeFinderResolver.cs index b7106e2e1d..2a4c611f8b 100644 --- a/src/Umbraco.Compat7/Web/Routing/ContentLastChangeFinderResolver.cs +++ b/src/Umbraco.Compat7/Web/Routing/ContentLastChangeFinderResolver.cs @@ -31,9 +31,9 @@ namespace Umbraco.Web.Routing _inner = inner; } - public bool TryFindContent(PublishedContentRequest contentRequest) + public bool TryFindContent(PublishedContentRequest frequest) { - return _inner.TryFindContent(contentRequest); + return _inner.TryFindContent(frequest); } } } diff --git a/src/Umbraco.Tests/Cache/PublishedCache/PublishedMediaCacheTests.cs b/src/Umbraco.Tests/Cache/PublishedCache/PublishedMediaCacheTests.cs index b4927ea605..567ff5d53a 100644 --- a/src/Umbraco.Tests/Cache/PublishedCache/PublishedMediaCacheTests.cs +++ b/src/Umbraco.Tests/Cache/PublishedCache/PublishedMediaCacheTests.cs @@ -48,7 +48,7 @@ namespace Umbraco.Tests.Cache.PublishedCache var mChild1 = global::umbraco.cms.businesslogic.media.Media.MakeNew("Child1", mType, user, mRoot1.Id); var mChild2 = global::umbraco.cms.businesslogic.media.Media.MakeNew("Child2", mType, user, mRoot2.Id); - var ctx = GetUmbracoContext("/test", 1234); + var ctx = GetUmbracoContext("/test"); var cache = new PublishedMediaCache(new XmlStore((XmlDocument) null), ServiceContext.MediaService, ServiceContext.UserService, new StaticCacheProvider(), ContentTypesCache); var roots = cache.GetAtRoot(); Assert.AreEqual(2, roots.Count()); @@ -65,7 +65,7 @@ namespace Umbraco.Tests.Cache.PublishedCache var mChild1 = global::umbraco.cms.businesslogic.media.Media.MakeNew("Child1", mType, user, mRoot.Id); //var publishedMedia = PublishedMediaTests.GetNode(mRoot.Id, GetUmbracoContext("/test", 1234)); - var umbracoContext = GetUmbracoContext("/test", 1234); + var umbracoContext = GetUmbracoContext("/test"); var cache = new PublishedMediaCache(new XmlStore((XmlDocument)null), Current.Services.MediaService, Current.Services.UserService, new StaticCacheProvider(), ContentTypesCache); var publishedMedia = cache.GetById(mRoot.Id); Assert.IsNotNull(publishedMedia); @@ -151,7 +151,7 @@ namespace Umbraco.Tests.Cache.PublishedCache [Test] public void Convert_From_Search_Result() { - var ctx = GetUmbracoContext("/test", 1234); + var ctx = GetUmbracoContext("/test"); var key = Guid.NewGuid(); var result = new SearchResult() @@ -189,7 +189,7 @@ namespace Umbraco.Tests.Cache.PublishedCache [Test] public void Convert_From_XPath_Navigator() { - var ctx = GetUmbracoContext("/test", 1234); + var ctx = GetUmbracoContext("/test"); var key = Guid.NewGuid(); var xmlDoc = GetMediaXml(); diff --git a/src/Umbraco.Tests/LibraryTests.cs b/src/Umbraco.Tests/LibraryTests.cs index 27d5cee342..79fc5fc3c1 100644 --- a/src/Umbraco.Tests/LibraryTests.cs +++ b/src/Umbraco.Tests/LibraryTests.cs @@ -25,7 +25,7 @@ namespace Umbraco.Tests /// Tests for the legacy library class /// [TestFixture] - public class LibraryTests : BaseRoutingTest + public class LibraryTests : BaseWebTest { public override void Initialize() { @@ -47,8 +47,8 @@ namespace Umbraco.Tests ContentTypesCache.Get(PublishedItemType.Content, "anything") .PropertyTypes.Count()); - var routingContext = GetRoutingContext("/test", 1234); - Umbraco.Web.Current.SetUmbracoContext(routingContext.UmbracoContext, true); + var umbracoContext = GetUmbracoContext("/test"); + Umbraco.Web.Current.SetUmbracoContext(umbracoContext, true); } /// diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentDataTableTests.cs b/src/Umbraco.Tests/PublishedContent/PublishedContentDataTableTests.cs index c73cebe3f5..1bbf39c84f 100644 --- a/src/Umbraco.Tests/PublishedContent/PublishedContentDataTableTests.cs +++ b/src/Umbraco.Tests/PublishedContent/PublishedContentDataTableTests.cs @@ -15,8 +15,8 @@ namespace Umbraco.Tests.PublishedContent /// Unit tests for IPublishedContent and extensions /// [TestFixture] - public class PublishedContentDataTableTests : BaseRoutingTest - { + public class PublishedContentDataTableTests : BaseWebTest + { public override void Initialize() { base.Initialize(); @@ -56,10 +56,10 @@ namespace Umbraco.Tests.PublishedContent } return allFields; }; - var routingContext = GetRoutingContext("/test"); + var umbracoContext = GetUmbracoContext("/test"); //set the UmbracoContext.Current since the extension methods rely on it - Umbraco.Web.Current.SetUmbracoContext(routingContext.UmbracoContext, true); + Umbraco.Web.Current.SetUmbracoContext(umbracoContext, true); } public override void TearDown() diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentRequestEngineTests.cs b/src/Umbraco.Tests/PublishedContent/PublishedContentRequestEngineTests.cs index 7e144568d9..7e2f41a5b7 100644 --- a/src/Umbraco.Tests/PublishedContent/PublishedContentRequestEngineTests.cs +++ b/src/Umbraco.Tests/PublishedContent/PublishedContentRequestEngineTests.cs @@ -2,98 +2,69 @@ using System; using System.Collections; using System.Collections.ObjectModel; using System.Globalization; -using System.Web.Security; using Moq; using NUnit.Framework; -using Umbraco.Core.Configuration.UmbracoSettings; -using Umbraco.Core.Models; using Umbraco.Core.Models.PublishedContent; using Umbraco.Tests.TestHelpers; -using Umbraco.Web.Routing; namespace Umbraco.Tests.PublishedContent { [TestFixture] - public class PublishedContentRequestEngineTests : BaseRoutingTest + public class PublishedContentRequestEngineTests : BaseWebTest { - [Test] - public void Ctor_Throws_On_Null_PCR() - { - Assert.Throws(() => new PublishedContentRequestEngine( - Mock.Of(), - null)); - } - [Test] public void ConfigureRequest_Returns_False_Without_HasPublishedContent() { - var routeCtx = GetRoutingContext("/test"); + var umbracoContext = GetUmbracoContext("/test"); + var facadeRouter = CreateFacadeRouter(); + var request = facadeRouter.CreateRequest(umbracoContext); + var result = facadeRouter.ConfigureRequest(request); - var pcre = new PublishedContentRequestEngine( - Mock.Of(), - new PublishedContentRequest( - routeCtx.UmbracoContext.CleanedUmbracoUrl, - routeCtx, - Mock.Of(), - s => new string[] { })); - - var result = pcre.ConfigureRequest(); Assert.IsFalse(result); } [Test] public void ConfigureRequest_Returns_False_When_IsRedirect() { - var routeCtx = GetRoutingContext("/test"); + var umbracoContext = GetUmbracoContext("/test"); + var facadeRouter = CreateFacadeRouter(); + var request = facadeRouter.CreateRequest(umbracoContext); + var content = GetPublishedContentMock(); + request.PublishedContent = content.Object; + request.Culture = new CultureInfo("en-AU"); + request.SetRedirect("/hello"); + var result = facadeRouter.ConfigureRequest(request); - var pcr = new PublishedContentRequest(routeCtx.UmbracoContext.CleanedUmbracoUrl, routeCtx, Mock.Of(), s => new string[] { }); - var pc = GetPublishedContentMock(); - pcr.PublishedContent = pc.Object; - pcr.Culture = new CultureInfo("en-AU"); - pcr.SetRedirect("/hello"); - var pcre = new PublishedContentRequestEngine( - Mock.Of(), - pcr); - - var result = pcre.ConfigureRequest(); Assert.IsFalse(result); } [Test] public void ConfigureRequest_Adds_HttpContext_Items_When_Published_Content_Assigned() { - var routeCtx = GetRoutingContext("/test"); - - var pcr = new PublishedContentRequest(routeCtx.UmbracoContext.CleanedUmbracoUrl, routeCtx, Mock.Of(), s => new string[] { }); - var pc = GetPublishedContentMock(); - pcr.PublishedContent = pc.Object; - pcr.Culture = new CultureInfo("en-AU"); - var pcre = new PublishedContentRequestEngine( - Mock.Of(), - pcr); - - pcre.ConfigureRequest(); + var umbracoContext = GetUmbracoContext("/test"); + var facadeRouter = CreateFacadeRouter(); + var request = facadeRouter.CreateRequest(umbracoContext); + var content = GetPublishedContentMock(); + request.PublishedContent = content.Object; + request.Culture = new CultureInfo("en-AU"); + facadeRouter.ConfigureRequest(request); - Assert.AreEqual(1, routeCtx.UmbracoContext.HttpContext.Items["pageID"]); - Assert.AreEqual(pcr.UmbracoPage.Elements.Count, ((Hashtable)routeCtx.UmbracoContext.HttpContext.Items["pageElements"]).Count); + Assert.AreEqual(1, umbracoContext.HttpContext.Items["pageID"]); + Assert.AreEqual(request.UmbracoPage.Elements.Count, ((Hashtable) umbracoContext.HttpContext.Items["pageElements"]).Count); } [Test] public void ConfigureRequest_Sets_UmbracoPage_When_Published_Content_Assigned() { - var routeCtx = GetRoutingContext("/test"); + var umbracoContext = GetUmbracoContext("/test"); + var facadeRouter = CreateFacadeRouter(); + var request = facadeRouter.CreateRequest(umbracoContext); + var content = GetPublishedContentMock(); + request.Culture = new CultureInfo("en-AU"); + request.PublishedContent = content.Object; + facadeRouter.ConfigureRequest(request); - var pcr = new PublishedContentRequest(routeCtx.UmbracoContext.CleanedUmbracoUrl, routeCtx, Mock.Of(), s => new string[] { }); - var pc = GetPublishedContentMock(); - pcr.Culture = new CultureInfo("en-AU"); - pcr.PublishedContent = pc.Object; - var pcre = new PublishedContentRequestEngine( - Mock.Of(), - pcr); - - pcre.ConfigureRequest(); - - Assert.IsNotNull(pcr.UmbracoPage); + Assert.IsNotNull(request.UmbracoPage); } private Mock GetPublishedContentMock() @@ -114,6 +85,5 @@ namespace Umbraco.Tests.PublishedContent pc.Setup(content => content.Properties).Returns(new Collection()); return pc; } - } } \ No newline at end of file diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentTestBase.cs b/src/Umbraco.Tests/PublishedContent/PublishedContentTestBase.cs index 6b3788076e..d11eb4a645 100644 --- a/src/Umbraco.Tests/PublishedContent/PublishedContentTestBase.cs +++ b/src/Umbraco.Tests/PublishedContent/PublishedContentTestBase.cs @@ -11,7 +11,7 @@ namespace Umbraco.Tests.PublishedContent /// /// Abstract base class for tests for published content and published media /// - public abstract class PublishedContentTestBase : BaseRoutingTest + public abstract class PublishedContentTestBase : BaseWebTest { public override void Initialize() { @@ -26,8 +26,8 @@ namespace Umbraco.Tests.PublishedContent var type = new AutoPublishedContentType(0, "anything", propertyTypes); ContentTypesCache.GetPublishedContentTypeByAlias = (alias) => type; - var rCtx = GetRoutingContext("/test", 1234); - Umbraco.Web.Current.SetUmbracoContext(rCtx.UmbracoContext, true); + var umbracoContext = GetUmbracoContext("/test"); + Umbraco.Web.Current.SetUmbracoContext(umbracoContext, true); } protected override void FreezeResolution() diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs b/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs index ce83e6acf9..ad98f6a3a8 100644 --- a/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs +++ b/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs @@ -116,7 +116,7 @@ namespace Umbraco.Tests.PublishedContent internal IPublishedContent GetNode(int id) { - var ctx = GetUmbracoContext("/test", 1234); + var ctx = GetUmbracoContext("/test"); var doc = ctx.ContentCache.GetById(id); Assert.IsNotNull(doc); return doc; diff --git a/src/Umbraco.Tests/PublishedContent/PublishedMediaTests.cs b/src/Umbraco.Tests/PublishedContent/PublishedMediaTests.cs index 194f0baac8..acad140448 100644 --- a/src/Umbraco.Tests/PublishedContent/PublishedMediaTests.cs +++ b/src/Umbraco.Tests/PublishedContent/PublishedMediaTests.cs @@ -56,7 +56,7 @@ namespace Umbraco.Tests.PublishedContent private IPublishedContent GetNode(int id) { - return GetNode(id, GetUmbracoContext("/test", 1234)); + return GetNode(id, GetUmbracoContext("/test")); } [Test] @@ -101,7 +101,7 @@ namespace Umbraco.Tests.PublishedContent session.WaitForChanges(); var searcher = indexer.GetSearcher(); - var ctx = GetUmbracoContext("/test", 1234); + var ctx = GetUmbracoContext("/test"); var cache = new PublishedMediaCache(ServiceContext.MediaService, ServiceContext.UserService, searcher, indexer, new StaticCacheProvider(), ContentTypesCache); //we are using the media.xml media to test the examine results implementation, see the media.xml file in the ExamineHelpers namespace @@ -133,7 +133,7 @@ namespace Umbraco.Tests.PublishedContent session.WaitForChanges(); var searcher = indexer.GetSearcher(); - var ctx = GetUmbracoContext("/test", 1234); + var ctx = GetUmbracoContext("/test"); var cache = new PublishedMediaCache(ServiceContext.MediaService, ServiceContext.UserService, searcher, indexer, new StaticCacheProvider(), ContentTypesCache); //ensure it is found @@ -177,7 +177,7 @@ namespace Umbraco.Tests.PublishedContent session.WaitForChanges(); var searcher = indexer.GetSearcher(); - var ctx = GetUmbracoContext("/test", 1234); + var ctx = GetUmbracoContext("/test"); var cache = new PublishedMediaCache(ServiceContext.MediaService, ServiceContext.UserService, searcher, indexer, new StaticCacheProvider(), ContentTypesCache); //we are using the media.xml media to test the examine results implementation, see the media.xml file in the ExamineHelpers namespace @@ -202,7 +202,7 @@ namespace Umbraco.Tests.PublishedContent session.WaitForChanges(); var searcher = indexer.GetSearcher(); - var ctx = GetUmbracoContext("/test", 1234); + var ctx = GetUmbracoContext("/test"); var cache = new PublishedMediaCache(ServiceContext.MediaService, ServiceContext.UserService, searcher, indexer, new StaticCacheProvider(), ContentTypesCache); //we are using the media.xml media to test the examine results implementation, see the media.xml file in the ExamineHelpers namespace @@ -227,7 +227,7 @@ namespace Umbraco.Tests.PublishedContent session.WaitForChanges(); var searcher = indexer.GetSearcher(); - var ctx = GetUmbracoContext("/test", 1234); + var ctx = GetUmbracoContext("/test"); var cache = new PublishedMediaCache(ServiceContext.MediaService, ServiceContext.UserService, searcher, indexer, new StaticCacheProvider(), ContentTypesCache); //we are using the media.xml media to test the examine results implementation, see the media.xml file in the ExamineHelpers namespace @@ -251,7 +251,7 @@ namespace Umbraco.Tests.PublishedContent indexer.RebuildIndex(); session.WaitForChanges(); - var ctx = GetUmbracoContext("/test", 1234); + var ctx = GetUmbracoContext("/test"); var searcher = indexer.GetSearcher(); var cache = new PublishedMediaCache(ServiceContext.MediaService, ServiceContext.UserService, searcher, indexer, new StaticCacheProvider(), ContentTypesCache); @@ -273,7 +273,7 @@ namespace Umbraco.Tests.PublishedContent indexer.RebuildIndex(); session.WaitForChanges(); - var ctx = GetUmbracoContext("/test", 1234); + var ctx = GetUmbracoContext("/test"); var searcher = indexer.GetSearcher(); var cache = new PublishedMediaCache(ServiceContext.MediaService, ServiceContext.UserService, searcher, indexer, new StaticCacheProvider(), ContentTypesCache); diff --git a/src/Umbraco.Tests/PublishedContent/RootNodeTests.cs b/src/Umbraco.Tests/PublishedContent/RootNodeTests.cs index bab3477324..77eab1dbb7 100644 --- a/src/Umbraco.Tests/PublishedContent/RootNodeTests.cs +++ b/src/Umbraco.Tests/PublishedContent/RootNodeTests.cs @@ -10,7 +10,7 @@ namespace Umbraco.Tests.PublishedContent [Test] public void PublishedContentHasNoRootNode() { - var ctx = GetUmbracoContext("/test", 1234); + var ctx = GetUmbracoContext("/test"); // there is no content node with ID -1 var content = ctx.ContentCache.GetById(-1); diff --git a/src/Umbraco.Tests/Routing/ContentFinderByAliasTests.cs b/src/Umbraco.Tests/Routing/ContentFinderByAliasTests.cs index f8cb9d1f94..d2922fbe39 100644 --- a/src/Umbraco.Tests/Routing/ContentFinderByAliasTests.cs +++ b/src/Umbraco.Tests/Routing/ContentFinderByAliasTests.cs @@ -1,6 +1,4 @@ -using Moq; using NUnit.Framework; -using Umbraco.Core.Logging; using Umbraco.Web.Routing; namespace Umbraco.Tests.Routing @@ -19,15 +17,15 @@ namespace Umbraco.Tests.Routing [TestCase("/alias43", 100121)] public void Lookup_By_Url_Alias(string urlAsString, int nodeMatch) { - var routingContext = GetRoutingContext(urlAsString); - var url = routingContext.UmbracoContext.CleanedUmbracoUrl; //very important to use the cleaned up umbraco url - var docRequest = new PublishedContentRequest(url, routingContext); + var umbracoContext = GetUmbracoContext(urlAsString); + var facadeRouter = CreateFacadeRouter(); + var frequest = facadeRouter.CreateRequest(umbracoContext); var lookup = new ContentFinderByUrlAlias(Logger); - var result = lookup.TryFindContent(docRequest); + var result = lookup.TryFindContent(frequest); Assert.IsTrue(result); - Assert.AreEqual(docRequest.PublishedContent.Id, nodeMatch); + Assert.AreEqual(frequest.PublishedContent.Id, nodeMatch); } protected override string GetXmlContent(int templateId) diff --git a/src/Umbraco.Tests/Routing/ContentFinderByAliasWithDomainsTests.cs b/src/Umbraco.Tests/Routing/ContentFinderByAliasWithDomainsTests.cs index d69a6133ed..5eb4a8f788 100644 --- a/src/Umbraco.Tests/Routing/ContentFinderByAliasWithDomainsTests.cs +++ b/src/Umbraco.Tests/Routing/ContentFinderByAliasWithDomainsTests.cs @@ -26,22 +26,22 @@ namespace Umbraco.Tests.Routing { //SetDomains1(); - var routingContext = GetRoutingContext(inputUrl); - var url = routingContext.UmbracoContext.CleanedUmbracoUrl; //very important to use the cleaned up umbraco url - var pcr = new PublishedContentRequest(url, routingContext); + var umbracoContext = GetUmbracoContext(inputUrl); + var facadeRouter = CreateFacadeRouter(); + var request = facadeRouter.CreateRequest(umbracoContext); // must lookup domain - pcr.Engine.FindDomain(); + facadeRouter.FindDomain(request); if (expectedNode > 0) - Assert.AreEqual(expectedCulture, pcr.Culture.Name); + Assert.AreEqual(expectedCulture, request.Culture.Name); var finder = new ContentFinderByUrlAlias(Logger); - var result = finder.TryFindContent(pcr); + var result = finder.TryFindContent(request); if (expectedNode > 0) { Assert.IsTrue(result); - Assert.AreEqual(pcr.PublishedContent.Id, expectedNode); + Assert.AreEqual(request.PublishedContent.Id, expectedNode); } else { diff --git a/src/Umbraco.Tests/Routing/ContentFinderByIdTests.cs b/src/Umbraco.Tests/Routing/ContentFinderByIdTests.cs index d68b8190de..f78d378c33 100644 --- a/src/Umbraco.Tests/Routing/ContentFinderByIdTests.cs +++ b/src/Umbraco.Tests/Routing/ContentFinderByIdTests.cs @@ -1,31 +1,27 @@ -using Moq; using NUnit.Framework; -using Umbraco.Core.Logging; using Umbraco.Tests.TestHelpers; using Umbraco.Web.Routing; -using umbraco.BusinessLogic; -using umbraco.cms.businesslogic.template; namespace Umbraco.Tests.Routing { [TestFixture] - public class ContentFinderByIdTests : BaseRoutingTest - { + public class ContentFinderByIdTests : BaseWebTest + { [TestCase("/1046", 1046)] [TestCase("/1046.aspx", 1046)] public void Lookup_By_Id(string urlAsString, int nodeMatch) { - var routingContext = GetRoutingContext(urlAsString); - var url = routingContext.UmbracoContext.CleanedUmbracoUrl; //very important to use the cleaned up umbraco url - var docRequest = new PublishedContentRequest(url, routingContext); + var umbracoContext = GetUmbracoContext(urlAsString); + var facadeRouter = CreateFacadeRouter(); + var frequest = facadeRouter.CreateRequest(umbracoContext); var lookup = new ContentFinderByIdPath(Logger); - var result = lookup.TryFindContent(docRequest); + var result = lookup.TryFindContent(frequest); Assert.IsTrue(result); - Assert.AreEqual(docRequest.PublishedContent.Id, nodeMatch); + Assert.AreEqual(frequest.PublishedContent.Id, nodeMatch); } } } \ No newline at end of file diff --git a/src/Umbraco.Tests/Routing/ContentFinderByNiceUrlAndTemplateTests.cs b/src/Umbraco.Tests/Routing/ContentFinderByNiceUrlAndTemplateTests.cs index 0512ac303e..6b62dd4bb5 100644 --- a/src/Umbraco.Tests/Routing/ContentFinderByNiceUrlAndTemplateTests.cs +++ b/src/Umbraco.Tests/Routing/ContentFinderByNiceUrlAndTemplateTests.cs @@ -11,8 +11,8 @@ namespace Umbraco.Tests.Routing { [DatabaseTestBehavior(DatabaseBehavior.NewDbFileAndSchemaPerFixture)] [TestFixture] - public class ContentFinderByNiceUrlAndTemplateTests : BaseRoutingTest - { + public class ContentFinderByNiceUrlAndTemplateTests : BaseWebTest + { Template CreateTemplate(string alias) { var template = new Template(alias, alias); @@ -29,20 +29,19 @@ namespace Umbraco.Tests.Routing public void Match_Document_By_Url_With_Template(string urlAsString) { var template = CreateTemplate("test"); - var altTemplate = CreateTemplate("blah"); - var routingContext = GetRoutingContext(urlAsString, template); - var url = routingContext.UmbracoContext.CleanedUmbracoUrl; //very important to use the cleaned up umbraco url - var docRequest = new PublishedContentRequest(url, routingContext); + var umbracoContext = GetUmbracoContext(urlAsString, template.Id); + var facadeRouter = CreateFacadeRouter(); + var frequest = facadeRouter.CreateRequest(umbracoContext); var lookup = new ContentFinderByNiceUrlAndTemplate(Logger); SettingsForTests.HideTopLevelNodeFromPath = false; - var result = lookup.TryFindContent(docRequest); + var result = lookup.TryFindContent(frequest); Assert.IsTrue(result); - Assert.IsNotNull(docRequest.PublishedContent); - Assert.IsNotNull(docRequest.TemplateAlias); - Assert.AreEqual("blah".ToUpperInvariant(), docRequest.TemplateAlias.ToUpperInvariant()); + Assert.IsNotNull(frequest.PublishedContent); + Assert.IsNotNull(frequest.TemplateAlias); + Assert.AreEqual("blah".ToUpperInvariant(), frequest.TemplateAlias.ToUpperInvariant()); } } } \ No newline at end of file diff --git a/src/Umbraco.Tests/Routing/ContentFinderByNiceUrlTests.cs b/src/Umbraco.Tests/Routing/ContentFinderByNiceUrlTests.cs index b308a90028..f2eb62b3da 100644 --- a/src/Umbraco.Tests/Routing/ContentFinderByNiceUrlTests.cs +++ b/src/Umbraco.Tests/Routing/ContentFinderByNiceUrlTests.cs @@ -6,8 +6,8 @@ namespace Umbraco.Tests.Routing { [DatabaseTestBehavior(DatabaseBehavior.NewDbFileAndSchemaPerTest)] [TestFixture] - public class ContentFinderByNiceUrlTests : BaseRoutingTest - { + public class ContentFinderByNiceUrlTests : BaseWebTest + { [TestCase("/", 1046)] [TestCase("/default.aspx", 1046)] //this one is actually rather important since this is the path that comes through when we are running in pre-IIS 7 for the root document '/' ! [TestCase("/Sub1", 1173)] @@ -21,9 +21,9 @@ namespace Umbraco.Tests.Routing [TestCase("/test-page", 1172)] public void Match_Document_By_Url_Hide_Top_Level(string urlString, int expectedId) { - var routingContext = GetRoutingContext(urlString); - var url = routingContext.UmbracoContext.CleanedUmbracoUrl; //very important to use the cleaned up umbraco url - var docreq = new PublishedContentRequest(url, routingContext); + var umbracoContext = GetUmbracoContext(urlString); + var facadeRouter = CreateFacadeRouter(); + var frequest = facadeRouter.CreateRequest(umbracoContext); var lookup = new ContentFinderByNiceUrl(Logger); SettingsForTests.HideTopLevelNodeFromPath = true; @@ -33,12 +33,12 @@ namespace Umbraco.Tests.Routing if (urlString == "/home/sub1") System.Diagnostics.Debugger.Break(); - var result = lookup.TryFindContent(docreq); + var result = lookup.TryFindContent(frequest); if (expectedId > 0) { Assert.IsTrue(result); - Assert.AreEqual(expectedId, docreq.PublishedContent.Id); + Assert.AreEqual(expectedId, frequest.PublishedContent.Id); } else { @@ -54,18 +54,18 @@ namespace Umbraco.Tests.Routing [TestCase("/home/Sub1.aspx", 1173)] public void Match_Document_By_Url(string urlString, int expectedId) { - var routingContext = GetRoutingContext(urlString); - var url = routingContext.UmbracoContext.CleanedUmbracoUrl; //very important to use the cleaned up umbraco url - var docreq = new PublishedContentRequest(url, routingContext); + var umbracoContext = GetUmbracoContext(urlString); + var facadeRouter = CreateFacadeRouter(); + var frequest = facadeRouter.CreateRequest(umbracoContext); var lookup = new ContentFinderByNiceUrl(Logger); SettingsForTests.HideTopLevelNodeFromPath = false; Assert.IsFalse(Core.Configuration.GlobalSettings.HideTopLevelNodeFromPath); - var result = lookup.TryFindContent(docreq); + var result = lookup.TryFindContent(frequest); Assert.IsTrue(result); - Assert.AreEqual(expectedId, docreq.PublishedContent.Id); + Assert.AreEqual(expectedId, frequest.PublishedContent.Id); } } } \ No newline at end of file diff --git a/src/Umbraco.Tests/Routing/ContentFinderByNiceUrlWithDomainsTests.cs b/src/Umbraco.Tests/Routing/ContentFinderByNiceUrlWithDomainsTests.cs index d90f205bd9..512979ab17 100644 --- a/src/Umbraco.Tests/Routing/ContentFinderByNiceUrlWithDomainsTests.cs +++ b/src/Umbraco.Tests/Routing/ContentFinderByNiceUrlWithDomainsTests.cs @@ -125,17 +125,17 @@ namespace Umbraco.Tests.Routing SettingsForTests.HideTopLevelNodeFromPath = true; - var routingContext = GetRoutingContext(url); - var uri = routingContext.UmbracoContext.CleanedUmbracoUrl; //very important to use the cleaned up umbraco url - var pcr = new PublishedContentRequest(uri, routingContext); + var umbracoContext = GetUmbracoContext(url); + var facadeRouter = CreateFacadeRouter(); + var frequest = facadeRouter.CreateRequest(umbracoContext); // must lookup domain else lookup by url fails - pcr.Engine.FindDomain(); + facadeRouter.FindDomain(frequest); var lookup = new ContentFinderByNiceUrl(Logger); - var result = lookup.TryFindContent(pcr); + var result = lookup.TryFindContent(frequest); Assert.IsTrue(result); - Assert.AreEqual(expectedId, pcr.PublishedContent.Id); + Assert.AreEqual(expectedId, frequest.PublishedContent.Id); } [TestCase("http://domain1.com/", 1001, "en-US")] @@ -166,18 +166,18 @@ namespace Umbraco.Tests.Routing SettingsForTests.HideTopLevelNodeFromPath = true; - var routingContext = GetRoutingContext(url); - var uri = routingContext.UmbracoContext.CleanedUmbracoUrl; //very important to use the cleaned up umbraco url - var pcr = new PublishedContentRequest(uri, routingContext); + var umbracoContext = GetUmbracoContext(url); + var facadeRouter = CreateFacadeRouter(); + var frequest = facadeRouter.CreateRequest(umbracoContext); // must lookup domain else lookup by url fails - pcr.Engine.FindDomain(); - Assert.AreEqual(expectedCulture, pcr.Culture.Name); + facadeRouter.FindDomain(frequest); + Assert.AreEqual(expectedCulture, frequest.Culture.Name); var lookup = new ContentFinderByNiceUrl(Logger); - var result = lookup.TryFindContent(pcr); + var result = lookup.TryFindContent(frequest); Assert.IsTrue(result); - Assert.AreEqual(expectedId, pcr.PublishedContent.Id); + Assert.AreEqual(expectedId, frequest.PublishedContent.Id); } } } diff --git a/src/Umbraco.Tests/Routing/ContentFinderByPageIdQueryTests.cs b/src/Umbraco.Tests/Routing/ContentFinderByPageIdQueryTests.cs index 912e88bb15..47a650015e 100644 --- a/src/Umbraco.Tests/Routing/ContentFinderByPageIdQueryTests.cs +++ b/src/Umbraco.Tests/Routing/ContentFinderByPageIdQueryTests.cs @@ -6,8 +6,8 @@ using Umbraco.Web.Routing; namespace Umbraco.Tests.Routing { [TestFixture] - public class ContentFinderByPageIdQueryTests : BaseRoutingTest - { + public class ContentFinderByPageIdQueryTests : BaseWebTest + { [TestCase("/?umbPageId=1046", 1046)] [TestCase("/?UMBPAGEID=1046", 1046)] [TestCase("/default.aspx?umbPageId=1046", 1046)] //TODO: Should this match?? @@ -15,21 +15,21 @@ namespace Umbraco.Tests.Routing [TestCase("/some/other/page.aspx?umbPageId=1046", 1046)] //TODO: Should this match?? public void Lookup_By_Page_Id(string urlAsString, int nodeMatch) { - var routingContext = GetRoutingContext(urlAsString); - var url = routingContext.UmbracoContext.CleanedUmbracoUrl; //very important to use the cleaned up umbraco url - var docRequest = new PublishedContentRequest(url, routingContext); + var umbracoContext = GetUmbracoContext(urlAsString); + var facadeRouter = CreateFacadeRouter(); + var frequest = facadeRouter.CreateRequest(umbracoContext); var lookup = new ContentFinderByPageIdQuery(); //we need to manually stub the return output of HttpContext.Request["umbPageId"] - var requestMock = Mock.Get(routingContext.UmbracoContext.HttpContext.Request); + var requestMock = Mock.Get(umbracoContext.HttpContext.Request); requestMock.Setup(x => x["umbPageID"]) - .Returns(routingContext.UmbracoContext.HttpContext.Request.QueryString["umbPageID"]); + .Returns(umbracoContext.HttpContext.Request.QueryString["umbPageID"]); - var result = lookup.TryFindContent(docRequest); + var result = lookup.TryFindContent(frequest); Assert.IsTrue(result); - Assert.AreEqual(docRequest.PublishedContent.Id, nodeMatch); + Assert.AreEqual(frequest.PublishedContent.Id, nodeMatch); } } } \ No newline at end of file diff --git a/src/Umbraco.Tests/Routing/DomainsAndCulturesTests.cs b/src/Umbraco.Tests/Routing/DomainsAndCulturesTests.cs index 0643d8073b..075d534729 100644 --- a/src/Umbraco.Tests/Routing/DomainsAndCulturesTests.cs +++ b/src/Umbraco.Tests/Routing/DomainsAndCulturesTests.cs @@ -269,22 +269,21 @@ namespace Umbraco.Tests.Routing { SetDomains1(); - var routingContext = GetRoutingContext(inputUrl); - var url = routingContext.UmbracoContext.CleanedUmbracoUrl; - //very important to use the cleaned up umbraco url - var pcr = new PublishedContentRequest(url, routingContext); + var umbracoContext = GetUmbracoContext(inputUrl); + var facadeRouter = CreateFacadeRouter(); + var frequest = facadeRouter.CreateRequest(umbracoContext); // lookup domain - pcr.Engine.FindDomain(); + facadeRouter.FindDomain(frequest); - Assert.AreEqual(expectedCulture, pcr.Culture.Name); + Assert.AreEqual(expectedCulture, frequest.Culture.Name); SettingsForTests.HideTopLevelNodeFromPath = false; var finder = new ContentFinderByNiceUrl(Logger); - var result = finder.TryFindContent(pcr); + var result = finder.TryFindContent(frequest); Assert.IsTrue(result); - Assert.AreEqual(pcr.PublishedContent.Id, expectedNode); + Assert.AreEqual(frequest.PublishedContent.Id, expectedNode); } #region Cases @@ -317,25 +316,24 @@ namespace Umbraco.Tests.Routing // defaults depend on test environment expectedCulture = expectedCulture ?? System.Threading.Thread.CurrentThread.CurrentUICulture.Name; - var routingContext = GetRoutingContext(inputUrl); - var url = routingContext.UmbracoContext.CleanedUmbracoUrl; - //very important to use the cleaned up umbraco url - var pcr = new PublishedContentRequest(url, routingContext); + var umbracoContext = GetUmbracoContext(inputUrl); + var facadeRouter = CreateFacadeRouter(); + var frequest = facadeRouter.CreateRequest(umbracoContext); // lookup domain - pcr.Engine.FindDomain(); + facadeRouter.FindDomain(frequest); // find document SettingsForTests.HideTopLevelNodeFromPath = false; var finder = new ContentFinderByNiceUrl(Logger); - var result = finder.TryFindContent(pcr); + var result = finder.TryFindContent(frequest); // apply wildcard domain - pcr.Engine.HandleWildcardDomains(); + facadeRouter.HandleWildcardDomains(frequest); Assert.IsTrue(result); - Assert.AreEqual(expectedCulture, pcr.Culture.Name); - Assert.AreEqual(pcr.PublishedContent.Id, expectedNode); + Assert.AreEqual(expectedCulture, frequest.Culture.Name); + Assert.AreEqual(frequest.PublishedContent.Id, expectedNode); } @@ -374,8 +372,7 @@ namespace Umbraco.Tests.Routing } }); - var routingContext = GetRoutingContext("http://anything/"); - var umbracoContext = routingContext.UmbracoContext; + var umbracoContext = GetUmbracoContext("http://anything/"); var content = umbracoContext.ContentCache.GetById(nodeId); Assert.IsNotNull(content); diff --git a/src/Umbraco.Tests/Routing/NiceUrlProviderTests.cs b/src/Umbraco.Tests/Routing/NiceUrlProviderTests.cs index ee1abf2f30..7346e85069 100644 --- a/src/Umbraco.Tests/Routing/NiceUrlProviderTests.cs +++ b/src/Umbraco.Tests/Routing/NiceUrlProviderTests.cs @@ -12,8 +12,8 @@ namespace Umbraco.Tests.Routing { [DatabaseTestBehavior(DatabaseBehavior.NewDbFileAndSchemaPerFixture)] [TestFixture] - public class NiceUrlProviderTests : BaseRoutingTest - { + public class NiceUrlProviderTests : BaseWebTest + { protected override void FreezeResolution() { base.FreezeResolution(); @@ -38,7 +38,7 @@ namespace Umbraco.Tests.Routing [Test] public void Ensure_Cache_Is_Correct() { - var routingContext = GetRoutingContext("/test", 1111); + var umbracoContext = GetUmbracoContext("/test", 1111); SettingsForTests.UseDirectoryUrls = true; SettingsForTests.HideTopLevelNodeFromPath = false; @@ -58,18 +58,18 @@ namespace Umbraco.Tests.Routing foreach (var sample in samples) { - var result = routingContext.UrlProvider.GetUrl(sample.Key); + var result = umbracoContext.UrlProvider.GetUrl(sample.Key); Assert.AreEqual(sample.Value, result); } var randomSample = new KeyValuePair(1177, "/home/sub1/custom-sub-1"); for (int i = 0; i < 5; i++) { - var result = routingContext.UrlProvider.GetUrl(randomSample.Key); + var result = umbracoContext.UrlProvider.GetUrl(randomSample.Key); Assert.AreEqual(randomSample.Value, result); } - var cache = routingContext.UmbracoContext.ContentCache as PublishedContentCache; + var cache = umbracoContext.ContentCache as PublishedContentCache; if (cache == null) throw new Exception("Unsupported IPublishedContentCache, only the Xml one is supported."); var cachedRoutes = cache.RoutesCache.GetCachedRoutes(); Assert.AreEqual(8, cachedRoutes.Count); @@ -102,14 +102,14 @@ namespace Umbraco.Tests.Routing [TestCase(1172, "/test-page/")] public void Get_Nice_Url_Not_Hiding_Top_Level(int nodeId, string niceUrlMatch) { - var routingContext = GetRoutingContext("/test", 1111); + var umbracoContext = GetUmbracoContext("/test", 1111); SettingsForTests.UseDirectoryUrls = true; SettingsForTests.HideTopLevelNodeFromPath = false; var requestMock = Mock.Get(_umbracoSettings.RequestHandler); requestMock.Setup(x => x.UseDomainPrefixes).Returns(false); - var result = routingContext.UrlProvider.GetUrl(nodeId); + var result = umbracoContext.UrlProvider.GetUrl(nodeId); Assert.AreEqual(niceUrlMatch, result); } @@ -126,14 +126,14 @@ namespace Umbraco.Tests.Routing [TestCase(1172, "/test-page/")] // not hidden because not first root public void Get_Nice_Url_Hiding_Top_Level(int nodeId, string niceUrlMatch) { - var routingContext = GetRoutingContext("/test", 1111); + var umbracoContext = GetUmbracoContext("/test", 1111); SettingsForTests.UseDirectoryUrls = true; SettingsForTests.HideTopLevelNodeFromPath = true; var requestMock = Mock.Get(_umbracoSettings.RequestHandler); requestMock.Setup(x => x.UseDomainPrefixes).Returns(false); - var result = routingContext.UrlProvider.GetUrl(nodeId); + var result = umbracoContext.UrlProvider.GetUrl(nodeId); Assert.AreEqual(niceUrlMatch, result); } @@ -145,24 +145,22 @@ namespace Umbraco.Tests.Routing var requestMock = Mock.Get(_umbracoSettings.RequestHandler); requestMock.Setup(x => x.UseDomainPrefixes).Returns(false); - var routingContext = GetRoutingContext("http://example.com/test", 1111, umbracoSettings: _umbracoSettings); + var umbracoContext = GetUmbracoContext("http://example.com/test", 1111, umbracoSettings: _umbracoSettings); - - - Assert.AreEqual("/home/sub1/custom-sub-1/", routingContext.UrlProvider.GetUrl(1177)); + Assert.AreEqual("/home/sub1/custom-sub-1/", umbracoContext.UrlProvider.GetUrl(1177)); requestMock.Setup(x => x.UseDomainPrefixes).Returns(true); - Assert.AreEqual("http://example.com/home/sub1/custom-sub-1/", routingContext.UrlProvider.GetUrl(1177)); + Assert.AreEqual("http://example.com/home/sub1/custom-sub-1/", umbracoContext.UrlProvider.GetUrl(1177)); requestMock.Setup(x => x.UseDomainPrefixes).Returns(false); - routingContext.UrlProvider.Mode = UrlProviderMode.Absolute; - Assert.AreEqual("http://example.com/home/sub1/custom-sub-1/", routingContext.UrlProvider.GetUrl(1177)); + umbracoContext.UrlProvider.Mode = UrlProviderMode.Absolute; + Assert.AreEqual("http://example.com/home/sub1/custom-sub-1/", umbracoContext.UrlProvider.GetUrl(1177)); } [Test] public void Get_Nice_Url_Unpublished() { - var routingContext = GetRoutingContext("http://example.com/test", 1111); + var umbracoContext = GetUmbracoContext("http://example.com/test", 1111); SettingsForTests.UseDirectoryUrls = true; SettingsForTests.HideTopLevelNodeFromPath = false; @@ -171,17 +169,17 @@ namespace Umbraco.Tests.Routing var requestMock = Mock.Get(_umbracoSettings.RequestHandler); requestMock.Setup(x => x.UseDomainPrefixes).Returns(false); - Assert.AreEqual("#", routingContext.UrlProvider.GetUrl(999999)); + Assert.AreEqual("#", umbracoContext.UrlProvider.GetUrl(999999)); requestMock.Setup(x => x.UseDomainPrefixes).Returns(true); - Assert.AreEqual("#", routingContext.UrlProvider.GetUrl(999999)); + Assert.AreEqual("#", umbracoContext.UrlProvider.GetUrl(999999)); requestMock.Setup(x => x.UseDomainPrefixes).Returns(false); - routingContext.UrlProvider.Mode = UrlProviderMode.Absolute; + umbracoContext.UrlProvider.Mode = UrlProviderMode.Absolute; - Assert.AreEqual("#", routingContext.UrlProvider.GetUrl(999999)); + Assert.AreEqual("#", umbracoContext.UrlProvider.GetUrl(999999)); } } } diff --git a/src/Umbraco.Tests/Routing/NiceUrlsProviderWithDomainsTests.cs b/src/Umbraco.Tests/Routing/NiceUrlsProviderWithDomainsTests.cs index e20ab65662..407bd13380 100644 --- a/src/Umbraco.Tests/Routing/NiceUrlsProviderWithDomainsTests.cs +++ b/src/Umbraco.Tests/Routing/NiceUrlsProviderWithDomainsTests.cs @@ -179,7 +179,7 @@ namespace Umbraco.Tests.Routing var request = Mock.Get(settings.RequestHandler); request.Setup(x => x.UseDomainPrefixes).Returns(false); - var routingContext = GetRoutingContext("/test", 1111, umbracoSettings: settings); + var umbracoContext = GetUmbracoContext("/test", 1111, umbracoSettings: settings); SettingsForTests.UseDirectoryUrls = true; SettingsForTests.HideTopLevelNodeFromPath = false; // ignored w/domains @@ -187,7 +187,7 @@ namespace Umbraco.Tests.Routing SetDomains1(); var currentUri = new Uri(currentUrl); - var result = routingContext.UrlProvider.GetUrl(nodeId, currentUri, absolute); + var result = umbracoContext.UrlProvider.GetUrl(nodeId, currentUri, absolute); Assert.AreEqual(expected, result); } @@ -210,7 +210,7 @@ namespace Umbraco.Tests.Routing var request = Mock.Get(settings.RequestHandler); request.Setup(x => x.UseDomainPrefixes).Returns(false); - var routingContext = GetRoutingContext("/test", 1111, umbracoSettings: settings); + var umbracoContext = GetUmbracoContext("/test", 1111, umbracoSettings: settings); SettingsForTests.UseDirectoryUrls = true; SettingsForTests.HideTopLevelNodeFromPath = false; // ignored w/domains @@ -218,7 +218,7 @@ namespace Umbraco.Tests.Routing SetDomains2(); var currentUri = new Uri(currentUrl); - var result = routingContext.UrlProvider.GetUrl(nodeId, currentUri, absolute); + var result = umbracoContext.UrlProvider.GetUrl(nodeId, currentUri, absolute); Assert.AreEqual(expected, result); } @@ -233,7 +233,7 @@ namespace Umbraco.Tests.Routing var request = Mock.Get(settings.RequestHandler); request.Setup(x => x.UseDomainPrefixes).Returns(false); - var routingContext = GetRoutingContext("/test", 1111, umbracoSettings: settings); + var umbracoContext = GetUmbracoContext("/test", 1111, umbracoSettings: settings); SettingsForTests.UseDirectoryUrls = true; SettingsForTests.HideTopLevelNodeFromPath = false; // ignored w/domains @@ -241,7 +241,7 @@ namespace Umbraco.Tests.Routing SetDomains3(); var currentUri = new Uri(currentUrl); - var result = routingContext.UrlProvider.GetUrl(nodeId, currentUri, absolute); + var result = umbracoContext.UrlProvider.GetUrl(nodeId, currentUri, absolute); Assert.AreEqual(expected, result); } @@ -262,7 +262,7 @@ namespace Umbraco.Tests.Routing var request = Mock.Get(settings.RequestHandler); request.Setup(x => x.UseDomainPrefixes).Returns(false); - var routingContext = GetRoutingContext("/test", 1111, umbracoSettings: settings); + var umbracoContext = GetUmbracoContext("/test", 1111, umbracoSettings: settings); SettingsForTests.UseDirectoryUrls = true; SettingsForTests.HideTopLevelNodeFromPath = false; // ignored w/domains @@ -270,7 +270,7 @@ namespace Umbraco.Tests.Routing SetDomains4(); var currentUri = new Uri(currentUrl); - var result = routingContext.UrlProvider.GetUrl(nodeId, currentUri, absolute); + var result = umbracoContext.UrlProvider.GetUrl(nodeId, currentUri, absolute); Assert.AreEqual(expected, result); } @@ -281,7 +281,7 @@ namespace Umbraco.Tests.Routing var request = Mock.Get(settings.RequestHandler); request.Setup(x => x.UseDomainPrefixes).Returns(false); - var routingContext = GetRoutingContext("/test", 1111, umbracoSettings: settings); + var umbracoContext = GetUmbracoContext("/test", 1111, umbracoSettings: settings); SettingsForTests.UseDirectoryUrls = true; SettingsForTests.HideTopLevelNodeFromPath = false; // ignored w/domains @@ -289,19 +289,19 @@ namespace Umbraco.Tests.Routing SetDomains4(); string ignore; - ignore = routingContext.UrlProvider.GetUrl(1001, new Uri("http://domain1.com"), false); - ignore = routingContext.UrlProvider.GetUrl(10011, new Uri("http://domain1.com"), false); - ignore = routingContext.UrlProvider.GetUrl(100111, new Uri("http://domain1.com"), false); - ignore = routingContext.UrlProvider.GetUrl(10012, new Uri("http://domain1.com"), false); - ignore = routingContext.UrlProvider.GetUrl(100121, new Uri("http://domain1.com"), false); - ignore = routingContext.UrlProvider.GetUrl(10013, new Uri("http://domain1.com"), false); - ignore = routingContext.UrlProvider.GetUrl(1002, new Uri("http://domain1.com"), false); - ignore = routingContext.UrlProvider.GetUrl(1001, new Uri("http://domain2.com"), false); - ignore = routingContext.UrlProvider.GetUrl(10011, new Uri("http://domain2.com"), false); - ignore = routingContext.UrlProvider.GetUrl(100111, new Uri("http://domain2.com"), false); - ignore = routingContext.UrlProvider.GetUrl(1002, new Uri("http://domain2.com"), false); + ignore = umbracoContext.UrlProvider.GetUrl(1001, new Uri("http://domain1.com"), false); + ignore = umbracoContext.UrlProvider.GetUrl(10011, new Uri("http://domain1.com"), false); + ignore = umbracoContext.UrlProvider.GetUrl(100111, new Uri("http://domain1.com"), false); + ignore = umbracoContext.UrlProvider.GetUrl(10012, new Uri("http://domain1.com"), false); + ignore = umbracoContext.UrlProvider.GetUrl(100121, new Uri("http://domain1.com"), false); + ignore = umbracoContext.UrlProvider.GetUrl(10013, new Uri("http://domain1.com"), false); + ignore = umbracoContext.UrlProvider.GetUrl(1002, new Uri("http://domain1.com"), false); + ignore = umbracoContext.UrlProvider.GetUrl(1001, new Uri("http://domain2.com"), false); + ignore = umbracoContext.UrlProvider.GetUrl(10011, new Uri("http://domain2.com"), false); + ignore = umbracoContext.UrlProvider.GetUrl(100111, new Uri("http://domain2.com"), false); + ignore = umbracoContext.UrlProvider.GetUrl(1002, new Uri("http://domain2.com"), false); - var cache = routingContext.UmbracoContext.ContentCache as PublishedContentCache; + var cache = umbracoContext.ContentCache as PublishedContentCache; if (cache == null) throw new Exception("Unsupported IPublishedContentCache, only the Xml one is supported."); var cachedRoutes = cache.RoutesCache.GetCachedRoutes(); Assert.AreEqual(7, cachedRoutes.Count); @@ -318,15 +318,15 @@ namespace Umbraco.Tests.Routing CheckRoute(cachedRoutes, cachedIds, 1002, "/1002"); // use the cache - Assert.AreEqual("/", routingContext.UrlProvider.GetUrl(1001, new Uri("http://domain1.com"), false)); - Assert.AreEqual("/en/", routingContext.UrlProvider.GetUrl(10011, new Uri("http://domain1.com"), false)); - Assert.AreEqual("/en/1001-1-1/", routingContext.UrlProvider.GetUrl(100111, new Uri("http://domain1.com"), false)); - Assert.AreEqual("/fr/", routingContext.UrlProvider.GetUrl(10012, new Uri("http://domain1.com"), false)); - Assert.AreEqual("/fr/1001-2-1/", routingContext.UrlProvider.GetUrl(100121, new Uri("http://domain1.com"), false)); - Assert.AreEqual("/1001-3/", routingContext.UrlProvider.GetUrl(10013, new Uri("http://domain1.com"), false)); - Assert.AreEqual("/1002/", routingContext.UrlProvider.GetUrl(1002, new Uri("http://domain1.com"), false)); + Assert.AreEqual("/", umbracoContext.UrlProvider.GetUrl(1001, new Uri("http://domain1.com"), false)); + Assert.AreEqual("/en/", umbracoContext.UrlProvider.GetUrl(10011, new Uri("http://domain1.com"), false)); + Assert.AreEqual("/en/1001-1-1/", umbracoContext.UrlProvider.GetUrl(100111, new Uri("http://domain1.com"), false)); + Assert.AreEqual("/fr/", umbracoContext.UrlProvider.GetUrl(10012, new Uri("http://domain1.com"), false)); + Assert.AreEqual("/fr/1001-2-1/", umbracoContext.UrlProvider.GetUrl(100121, new Uri("http://domain1.com"), false)); + Assert.AreEqual("/1001-3/", umbracoContext.UrlProvider.GetUrl(10013, new Uri("http://domain1.com"), false)); + Assert.AreEqual("/1002/", umbracoContext.UrlProvider.GetUrl(1002, new Uri("http://domain1.com"), false)); - Assert.AreEqual("http://domain1.com/fr/1001-2-1/", routingContext.UrlProvider.GetUrl(100121, new Uri("http://domain2.com"), false)); + Assert.AreEqual("http://domain1.com/fr/1001-2-1/", umbracoContext.UrlProvider.GetUrl(100121, new Uri("http://domain2.com"), false)); } void CheckRoute(IDictionary routes, IDictionary ids, int id, string route) @@ -344,43 +344,43 @@ namespace Umbraco.Tests.Routing var requestMock = Mock.Get(settings.RequestHandler); requestMock.Setup(x => x.UseDomainPrefixes).Returns(false); - var routingContext = GetRoutingContext("http://domain1.com/test", 1111, umbracoSettings: settings); + var umbracoContext = GetUmbracoContext("http://domain1.com/test", 1111, umbracoSettings: settings); SettingsForTests.UseDirectoryUrls = true; SettingsForTests.HideTopLevelNodeFromPath = false; SetDomains4(); - Assert.AreEqual("/en/1001-1-1/", routingContext.UrlProvider.GetUrl(100111)); - Assert.AreEqual("http://domain3.com/en/1003-1-1/", routingContext.UrlProvider.GetUrl(100311)); + Assert.AreEqual("/en/1001-1-1/", umbracoContext.UrlProvider.GetUrl(100111)); + Assert.AreEqual("http://domain3.com/en/1003-1-1/", umbracoContext.UrlProvider.GetUrl(100311)); requestMock.Setup(x => x.UseDomainPrefixes).Returns(true); - Assert.AreEqual("http://domain1.com/en/1001-1-1/", routingContext.UrlProvider.GetUrl(100111)); - Assert.AreEqual("http://domain3.com/en/1003-1-1/", routingContext.UrlProvider.GetUrl(100311)); + Assert.AreEqual("http://domain1.com/en/1001-1-1/", umbracoContext.UrlProvider.GetUrl(100111)); + Assert.AreEqual("http://domain3.com/en/1003-1-1/", umbracoContext.UrlProvider.GetUrl(100311)); requestMock.Setup(x => x.UseDomainPrefixes).Returns(false); - routingContext.UrlProvider.Mode = UrlProviderMode.Absolute; + umbracoContext.UrlProvider.Mode = UrlProviderMode.Absolute; - Assert.AreEqual("http://domain1.com/en/1001-1-1/", routingContext.UrlProvider.GetUrl(100111)); - Assert.AreEqual("http://domain3.com/en/1003-1-1/", routingContext.UrlProvider.GetUrl(100311)); + Assert.AreEqual("http://domain1.com/en/1001-1-1/", umbracoContext.UrlProvider.GetUrl(100111)); + Assert.AreEqual("http://domain3.com/en/1003-1-1/", umbracoContext.UrlProvider.GetUrl(100311)); } [Test] public void Get_Nice_Url_Alternate() { var settings = SettingsForTests.GenerateMockSettings(); - var routingContext = GetRoutingContext("http://domain1.com/en/test", 1111, umbracoSettings: settings); + var umbracoContext = GetUmbracoContext("http://domain1.com/en/test", 1111, umbracoSettings: settings); SettingsForTests.UseDirectoryUrls = true; SettingsForTests.HideTopLevelNodeFromPath = false; SetDomains5(); - var url = routingContext.UrlProvider.GetUrl(100111, true); + var url = umbracoContext.UrlProvider.GetUrl(100111, true); Assert.AreEqual("http://domain1.com/en/1001-1-1/", url); - var result = routingContext.UrlProvider.GetOtherUrls(100111).ToArray(); + var result = umbracoContext.UrlProvider.GetOtherUrls(100111).ToArray(); Assert.AreEqual(2, result.Count()); Assert.IsTrue(result.Contains("http://domain1a.com/en/1001-1-1/")); diff --git a/src/Umbraco.Tests/Routing/RenderRouteHandlerTests.cs b/src/Umbraco.Tests/Routing/RenderRouteHandlerTests.cs index 099ceaa7f1..f0bdecd8fb 100644 --- a/src/Umbraco.Tests/Routing/RenderRouteHandlerTests.cs +++ b/src/Umbraco.Tests/Routing/RenderRouteHandlerTests.cs @@ -23,8 +23,8 @@ namespace Umbraco.Tests.Routing { [DatabaseTestBehavior(DatabaseBehavior.NewDbFileAndSchemaPerFixture)] [TestFixture] - public class RenderRouteHandlerTests : BaseRoutingTest - { + public class RenderRouteHandlerTests : BaseWebTest + { public override void Initialize() { base.Initialize(); @@ -32,6 +32,7 @@ namespace Umbraco.Tests.Routing SettingsForTests.UmbracoPath = "~/umbraco"; WebRuntimeComponent.CreateRoutes( + new TestUmbracoContextAccessor(), new SurfaceControllerTypeCollection(Enumerable.Empty()), new UmbracoApiControllerTypeCollection(Enumerable.Empty())); } @@ -95,20 +96,17 @@ namespace Umbraco.Tests.Routing { var template = CreateTemplate("homePage"); var route = RouteTable.Routes["Umbraco_default"]; - var routeData = new RouteData() { Route = route }; - var routingContext = GetRoutingContext("~/dummy-page", template.Id, routeData); - var docRequest = new PublishedContentRequest(routingContext.UmbracoContext.CleanedUmbracoUrl, routingContext) - { - PublishedContent = routingContext.UmbracoContext.ContentCache.GetById(1174), - TemplateModel = template, - RenderingEngine = RenderingEngine.Mvc - }; + var routeData = new RouteData { Route = route }; + var umbracoContext = GetUmbracoContext("~/dummy-page", template.Id, routeData); + var facadeRouter = CreateFacadeRouter(); + var frequest = facadeRouter.CreateRequest(umbracoContext); + frequest.PublishedContent = umbracoContext.ContentCache.GetById(1174); + frequest.TemplateModel = template; + frequest.RenderingEngine = RenderingEngine.Mvc; - var handler = new RenderRouteHandler( - new TestControllerFactory(routingContext.UmbracoContext, Mock.Of()), - routingContext.UmbracoContext); + var handler = new RenderRouteHandler(umbracoContext, new TestControllerFactory(umbracoContext, Mock.Of())); - handler.GetHandlerForRoute(routingContext.UmbracoContext.HttpContext.Request.RequestContext, docRequest); + handler.GetHandlerForRoute(umbracoContext.HttpContext.Request.RequestContext, frequest); Assert.AreEqual("RenderMvc", routeData.Values["controller"].ToString()); //the route action will still be the one we've asked for because our RenderActionInvoker is the thing that decides // if the action matches. @@ -135,18 +133,15 @@ namespace Umbraco.Tests.Routing var template = CreateTemplate(templateName); var route = RouteTable.Routes["Umbraco_default"]; var routeData = new RouteData() {Route = route}; - var routingContext = GetRoutingContext("~/dummy-page", template.Id, routeData, true); - var docRequest = new PublishedContentRequest(routingContext.UmbracoContext.CleanedUmbracoUrl, routingContext) - { - PublishedContent = routingContext.UmbracoContext.ContentCache.GetById(1172), - TemplateModel = template - }; + var umbracoContext = GetUmbracoContext("~/dummy-page", template.Id, routeData, true); + var facadeRouter = CreateFacadeRouter(); + var frequest = facadeRouter.CreateRequest(umbracoContext); + frequest.PublishedContent = umbracoContext.ContentCache.GetById(1172); + frequest.TemplateModel = template; - var handler = new RenderRouteHandler( - new TestControllerFactory(routingContext.UmbracoContext, Mock.Of()), - routingContext.UmbracoContext); + var handler = new RenderRouteHandler(umbracoContext, new TestControllerFactory(umbracoContext, Mock.Of())); - handler.GetHandlerForRoute(routingContext.UmbracoContext.HttpContext.Request.RequestContext, docRequest); + handler.GetHandlerForRoute(umbracoContext.HttpContext.Request.RequestContext, frequest); Assert.AreEqual("CustomDocument", routeData.Values["controller"].ToString()); Assert.AreEqual( //global::umbraco.cms.helpers.Casing.SafeAlias(template.Alias), diff --git a/src/Umbraco.Tests/Routing/RoutesCacheTests.cs b/src/Umbraco.Tests/Routing/RoutesCacheTests.cs index a46ffdb584..14be184706 100644 --- a/src/Umbraco.Tests/Routing/RoutesCacheTests.cs +++ b/src/Umbraco.Tests/Routing/RoutesCacheTests.cs @@ -11,7 +11,7 @@ namespace Umbraco.Tests.Routing { [DatabaseTestBehavior(DatabaseBehavior.NewDbFileAndSchemaPerFixture)] [TestFixture] - public class RoutesCacheTests : BaseRoutingTest + public class RoutesCacheTests : BaseWebTest { [Test] public void U4_7939() diff --git a/src/Umbraco.Tests/Routing/UmbracoModuleTests.cs b/src/Umbraco.Tests/Routing/UmbracoModuleTests.cs index 946d524c69..26a96e7d1f 100644 --- a/src/Umbraco.Tests/Routing/UmbracoModuleTests.cs +++ b/src/Umbraco.Tests/Routing/UmbracoModuleTests.cs @@ -10,8 +10,8 @@ using Umbraco.Core.IO; namespace Umbraco.Tests.Routing { [TestFixture, RequiresSTA] - public class UmbracoModuleTests : BaseRoutingTest - { + public class UmbracoModuleTests : BaseWebTest + { private UmbracoModule _module; public override void Initialize() @@ -65,8 +65,7 @@ namespace Umbraco.Tests.Routing { var httpContextFactory = new FakeHttpContextFactory(url); var httpContext = httpContextFactory.HttpContext; - var routingContext = GetRoutingContext(url); - var umbracoContext = routingContext.UmbracoContext; + var umbracoContext = GetUmbracoContext(url); var result = _module.EnsureUmbracoRoutablePage(umbracoContext, httpContext); diff --git a/src/Umbraco.Tests/Routing/UrlRoutingTestBase.cs b/src/Umbraco.Tests/Routing/UrlRoutingTestBase.cs index 521a98238b..c169ccfc8d 100644 --- a/src/Umbraco.Tests/Routing/UrlRoutingTestBase.cs +++ b/src/Umbraco.Tests/Routing/UrlRoutingTestBase.cs @@ -2,12 +2,9 @@ using System.Collections.Generic; using System.Linq; using Moq; using NUnit.Framework; -using Umbraco.Core; using Umbraco.Core.Configuration.UmbracoSettings; using Umbraco.Core.Logging; using Umbraco.Core.Models; -using Umbraco.Core.Persistence; -using Umbraco.Core.Persistence.SqlSyntax; using Umbraco.Core.Services; using Umbraco.Tests.TestHelpers; @@ -15,7 +12,7 @@ namespace Umbraco.Tests.Routing { [DatabaseTestBehavior(DatabaseBehavior.NoDatabasePerFixture)] [TestFixture] - public abstract class UrlRoutingTestBase : BaseRoutingTest + public abstract class UrlRoutingTestBase : BaseWebTest { /// /// Sets up the mock domain service diff --git a/src/Umbraco.Tests/Routing/UrlsWithNestedDomains.cs b/src/Umbraco.Tests/Routing/UrlsWithNestedDomains.cs index bbedaa0a1f..dd33dbf052 100644 --- a/src/Umbraco.Tests/Routing/UrlsWithNestedDomains.cs +++ b/src/Umbraco.Tests/Routing/UrlsWithNestedDomains.cs @@ -12,6 +12,7 @@ using Umbraco.Web.PublishedCache.XmlPublishedCache; using Umbraco.Web.Routing; using umbraco.cms.businesslogic.web; using System.Configuration; +using Umbraco.Web; namespace Umbraco.Tests.Routing { @@ -35,31 +36,31 @@ namespace Umbraco.Tests.Routing SetDomains1(); - RoutingContext routingContext; + UmbracoContext umbracoContext; string url = "http://domain1.com/1001-1/1001-1-1"; // get the nice url for 100111 - routingContext = GetRoutingContext(url, 9999, umbracoSettings: settings); - Assert.AreEqual("http://domain2.com/1001-1-1/", routingContext.UrlProvider.GetUrl(100111, true)); + umbracoContext = GetUmbracoContext(url, 9999, umbracoSettings: settings); + Assert.AreEqual("http://domain2.com/1001-1-1/", umbracoContext.UrlProvider.GetUrl(100111, true)); // check that the proper route has been cached - var cache = routingContext.UmbracoContext.ContentCache as PublishedContentCache; + var cache = umbracoContext.ContentCache as PublishedContentCache; if (cache == null) throw new Exception("Unsupported IPublishedContentCache, only the Xml one is supported."); var cachedRoutes = cache.RoutesCache.GetCachedRoutes(); Assert.AreEqual("10011/1001-1-1", cachedRoutes[100111]); - // route a rogue url - url = "http://domain1.com/1001-1/1001-1-1"; - var uri = routingContext.UmbracoContext.CleanedUmbracoUrl; //very important to use the cleaned up umbraco url - var pcr = new PublishedContentRequest(uri, routingContext); - pcr.Engine.FindDomain(); - Assert.IsTrue(pcr.HasDomain); + // route a rogue url + var facadeRouter = CreateFacadeRouter(); + var frequest = facadeRouter.CreateRequest(umbracoContext); + + facadeRouter.FindDomain(frequest); + Assert.IsTrue(frequest.HasDomain); // check that it's been routed var lookup = new ContentFinderByNiceUrl(Logger); - var result = lookup.TryFindContent(pcr); + var result = lookup.TryFindContent(frequest); Assert.IsTrue(result); - Assert.AreEqual(100111, pcr.PublishedContent.Id); + Assert.AreEqual(100111, frequest.PublishedContent.Id); // has the cache been polluted? cachedRoutes = cache.RoutesCache.GetCachedRoutes(); @@ -67,7 +68,7 @@ namespace Umbraco.Tests.Routing //Assert.AreEqual("1001/1001-1/1001-1-1", cachedRoutes[100111]); // yes // what's the nice url now? - Assert.AreEqual("http://domain2.com/1001-1-1/", routingContext.UrlProvider.GetUrl(100111)); // good + Assert.AreEqual("http://domain2.com/1001-1-1/", umbracoContext.UrlProvider.GetUrl(100111)); // good //Assert.AreEqual("http://domain1.com/1001-1/1001-1-1", routingContext.NiceUrlProvider.GetNiceUrl(100111, true)); // bad } diff --git a/src/Umbraco.Tests/TestHelpers/BaseDatabaseFactoryTest.cs b/src/Umbraco.Tests/TestHelpers/BaseDatabaseFactoryTest.cs index 84c439ea2c..44839dd869 100644 --- a/src/Umbraco.Tests/TestHelpers/BaseDatabaseFactoryTest.cs +++ b/src/Umbraco.Tests/TestHelpers/BaseDatabaseFactoryTest.cs @@ -419,7 +419,7 @@ namespace Umbraco.Tests.TestHelpers protected DatabaseContext DatabaseContext => Core.DI.Current.DatabaseContext; - protected UmbracoContext GetUmbracoContext(string url, int templateId, RouteData routeData = null, bool setSingleton = false) + protected UmbracoContext GetUmbracoContext(string url, int templateId = 1234, RouteData routeData = null, bool setSingleton = false, IUmbracoSettingsSection umbracoSettings = null) { // ensure we have a PublishedCachesService var service = _facadeService as FacadeService; @@ -434,12 +434,14 @@ namespace Umbraco.Tests.TestHelpers return doc; }; + if (umbracoSettings == null) umbracoSettings = SettingsForTests.GetDefault(); + var httpContext = GetHttpContextFactory(url, routeData).HttpContext; var ctx = UmbracoContext.CreateContext( httpContext, service, new WebSecurity(httpContext, Core.DI.Current.Services.UserService), - Mock.Of(), + umbracoSettings, Enumerable.Empty()); if (setSingleton) diff --git a/src/Umbraco.Tests/TestHelpers/BaseRoutingTest.cs b/src/Umbraco.Tests/TestHelpers/BaseRoutingTest.cs deleted file mode 100644 index 7c43ec222b..0000000000 --- a/src/Umbraco.Tests/TestHelpers/BaseRoutingTest.cs +++ /dev/null @@ -1,74 +0,0 @@ -using System.Linq; -using System.Web.Routing; -using NUnit.Framework; -using Umbraco.Core.Configuration.UmbracoSettings; -using Umbraco.Core.Models; -using Umbraco.Tests.TestHelpers.Stubs; -using Umbraco.Web; -using Umbraco.Web.Routing; - -namespace Umbraco.Tests.TestHelpers -{ - [TestFixture, RequiresSTA] - public abstract class BaseRoutingTest : BaseWebTest - { - /// - /// Return a new RoutingContext - /// - /// - /// - /// The template Id to insert into the Xml cache file for each node, this is helpful for unit testing with templates but you - /// should normally create the template in the database with this id - /// - /// - /// set to true to also set the singleton UmbracoContext.Current to the context created with this method - /// - /// - protected RoutingContext GetRoutingContext(string url, int templateId, RouteData routeData = null, bool setUmbracoContextCurrent = false, IUmbracoSettingsSection umbracoSettings = null) - { - if (umbracoSettings == null) umbracoSettings = SettingsForTests.GetDefault(); - - var umbracoContext = GetUmbracoContext(url, templateId, routeData); - var urlProvider = new UrlProvider(umbracoContext, umbracoSettings.WebRouting, new IUrlProvider[] - { - new DefaultUrlProvider(umbracoSettings.RequestHandler, Current.Logger) - }); - var routingContext = new RoutingContext( - umbracoContext, - Enumerable.Empty(), - new FakeLastChanceFinder(), - urlProvider); - - //assign the routing context back to the umbraco context - umbracoContext.RoutingContext = routingContext; - - if (setUmbracoContextCurrent) - Umbraco.Web.Current.SetUmbracoContext(umbracoContext, true); - - return routingContext; - } - - /// - /// Return a new RoutingContext - /// - /// - /// - /// - /// - protected RoutingContext GetRoutingContext(string url, Template template, RouteData routeData = null) - { - return GetRoutingContext(url, template.Id, routeData); - } - - /// - /// Return a new RoutingContext that doesn't require testing based on template - /// - /// - /// - /// - protected RoutingContext GetRoutingContext(string url, RouteData routeData = null) - { - return GetRoutingContext(url, 1234, routeData); - } - } -} \ No newline at end of file diff --git a/src/Umbraco.Tests/TestHelpers/BaseWebTest.cs b/src/Umbraco.Tests/TestHelpers/BaseWebTest.cs index ee5cd0efbc..e4dba34b8d 100644 --- a/src/Umbraco.Tests/TestHelpers/BaseWebTest.cs +++ b/src/Umbraco.Tests/TestHelpers/BaseWebTest.cs @@ -1,13 +1,19 @@ +using System.Linq; +using Moq; using NUnit.Framework; +using Umbraco.Core.Configuration.UmbracoSettings; +using Umbraco.Core.Logging; using Umbraco.Core.Models.PublishedContent; using Umbraco.Tests.PublishedContent; +using Umbraco.Tests.TestHelpers.Stubs; +using Umbraco.Web; +using Umbraco.Web.Routing; namespace Umbraco.Tests.TestHelpers { [TestFixture, RequiresSTA] public abstract class BaseWebTest : BaseDatabaseFactoryTest { - [SetUp] public override void Initialize() { @@ -59,5 +65,15 @@ namespace Umbraco.Tests.TestHelpers "; } + + internal static FacadeRouter CreateFacadeRouter() + { + return new FacadeRouter( + Mock.Of(), + Enumerable.Empty(), + new FakeLastChanceFinder(), + null, + new ProfilingLogger(Mock.Of(), Mock.Of())); + } } } diff --git a/src/Umbraco.Tests/TestHelpers/Stubs/FakeLastChanceFinder.cs b/src/Umbraco.Tests/TestHelpers/Stubs/FakeLastChanceFinder.cs index c2d636c545..83cd02f1f5 100644 --- a/src/Umbraco.Tests/TestHelpers/Stubs/FakeLastChanceFinder.cs +++ b/src/Umbraco.Tests/TestHelpers/Stubs/FakeLastChanceFinder.cs @@ -2,9 +2,9 @@ using Umbraco.Web.Routing; namespace Umbraco.Tests.TestHelpers.Stubs { - internal class FakeLastChanceFinder : IContentFinder + internal class FakeLastChanceFinder : IContentLastChanceFinder { - public bool TryFindContent(PublishedContentRequest docRequest) + public bool TryFindContent(PublishedContentRequest frequest) { return false; } diff --git a/src/Umbraco.Tests/TestHelpers/TestUmbracoContextAccessor.cs b/src/Umbraco.Tests/TestHelpers/TestUmbracoContextAccessor.cs index a646977710..57f2a5a576 100644 --- a/src/Umbraco.Tests/TestHelpers/TestUmbracoContextAccessor.cs +++ b/src/Umbraco.Tests/TestHelpers/TestUmbracoContextAccessor.cs @@ -2,7 +2,7 @@ using Umbraco.Web; namespace Umbraco.Tests { - class TestUmbracoContextAccessor : IUmbracoContextAccessor + internal class TestUmbracoContextAccessor : IUmbracoContextAccessor { public UmbracoContext UmbracoContext { get; set; } } diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj index 2e1e071375..7d9b3a0d14 100644 --- a/src/Umbraco.Tests/Umbraco.Tests.csproj +++ b/src/Umbraco.Tests/Umbraco.Tests.csproj @@ -523,7 +523,6 @@ - diff --git a/src/Umbraco.Tests/Web/Mvc/SurfaceControllerTests.cs b/src/Umbraco.Tests/Web/Mvc/SurfaceControllerTests.cs index 282d9de5cb..c912ce0c43 100644 --- a/src/Umbraco.Tests/Web/Mvc/SurfaceControllerTests.cs +++ b/src/Umbraco.Tests/Web/Mvc/SurfaceControllerTests.cs @@ -172,17 +172,13 @@ namespace Umbraco.Tests.Web.Mvc var content = Mock.Of(publishedContent => publishedContent.Id == 12345); var contextBase = umbCtx.HttpContext; - var pcr = new PublishedContentRequest(new Uri("http://localhost/test"), - umbCtx.RoutingContext, - webRoutingSettings, - s => Enumerable.Empty()) - { - PublishedContent = content - }; + var facadeRouter = BaseWebTest.CreateFacadeRouter(); + var frequest = facadeRouter.CreateRequest(umbCtx, new Uri("http://localhost/test")); + frequest.PublishedContent = content; var routeDefinition = new RouteDefinition { - PublishedContentRequest = pcr + PublishedContentRequest = frequest }; var routeData = new RouteData(); diff --git a/src/Umbraco.Tests/Web/Mvc/UmbracoViewPageTests.cs b/src/Umbraco.Tests/Web/Mvc/UmbracoViewPageTests.cs index 556c7b1a60..13a9db75ff 100644 --- a/src/Umbraco.Tests/Web/Mvc/UmbracoViewPageTests.cs +++ b/src/Umbraco.Tests/Web/Mvc/UmbracoViewPageTests.cs @@ -397,29 +397,15 @@ namespace Umbraco.Tests.Web.Mvc logger, settings, "/dang", 0); - var urlProvider = new UrlProvider(umbracoContext, settings.WebRouting, new IUrlProvider[] - { - new DefaultUrlProvider(settings.RequestHandler, Current.Logger) - }); - var routingContext = new RoutingContext( - umbracoContext, - Enumerable.Empty(), - new FakeLastChanceFinder(), - urlProvider); - umbracoContext.RoutingContext = routingContext; + var facadeRouter = BaseWebTest.CreateFacadeRouter(); + var frequest = facadeRouter.CreateRequest(umbracoContext, new Uri("http://localhost/dang")); - var request = new PublishedContentRequest( - new Uri("http://localhost/dang"), - routingContext, - settings.WebRouting, - s => Enumerable.Empty()); - - request.Culture = CultureInfo.InvariantCulture; - umbracoContext.PublishedContentRequest = request; + frequest.Culture = CultureInfo.InvariantCulture; + umbracoContext.PublishedContentRequest = frequest; var context = new ViewContext(); context.RouteData = new RouteData(); - context.RouteData.DataTokens.Add(Umbraco.Core.Constants.Web.UmbracoContextDataToken, umbracoContext); + context.RouteData.DataTokens.Add(Core.Constants.Web.UmbracoContextDataToken, umbracoContext); return context; } diff --git a/src/Umbraco.Web/Mvc/EnsurePublishedContentRequestAttribute.cs b/src/Umbraco.Web/Mvc/EnsurePublishedContentRequestAttribute.cs index cce9acfb14..ce7778d33b 100644 --- a/src/Umbraco.Web/Mvc/EnsurePublishedContentRequestAttribute.cs +++ b/src/Umbraco.Web/Mvc/EnsurePublishedContentRequestAttribute.cs @@ -1,12 +1,8 @@ using System; -using System.Globalization; -using System.Linq; using System.Web.Mvc; -using Umbraco.Core.Models; using Umbraco.Web.Routing; using Umbraco.Core; using Umbraco.Core.Models.PublishedContent; -using Language = umbraco.cms.businesslogic.language.Language; namespace Umbraco.Web.Mvc { @@ -24,7 +20,6 @@ namespace Umbraco.Web.Mvc public class EnsurePublishedContentRequestAttribute : ActionFilterAttribute { private readonly string _dataTokenName; - private readonly string _culture; private UmbracoContext _umbracoContext; private readonly int? _contentId; private UmbracoHelper _helper; @@ -34,13 +29,11 @@ namespace Umbraco.Web.Mvc /// /// /// - /// - public EnsurePublishedContentRequestAttribute(UmbracoContext umbracoContext, int contentId, string culture = null) + public EnsurePublishedContentRequestAttribute(UmbracoContext umbracoContext, int contentId) { - if (umbracoContext == null) throw new ArgumentNullException("umbracoContext"); + if (umbracoContext == null) throw new ArgumentNullException(nameof(umbracoContext)); _umbracoContext = umbracoContext; _contentId = contentId; - _culture = culture; } /// @@ -66,13 +59,11 @@ namespace Umbraco.Web.Mvc /// /// /// - /// - public EnsurePublishedContentRequestAttribute(UmbracoContext umbracoContext, string dataTokenName, string culture = null) + public EnsurePublishedContentRequestAttribute(UmbracoContext umbracoContext, string dataTokenName) { - if (umbracoContext == null) throw new ArgumentNullException("umbracoContext"); + if (umbracoContext == null) throw new ArgumentNullException(nameof(umbracoContext)); _umbracoContext = umbracoContext; _dataTokenName = dataTokenName; - _culture = culture; } /// @@ -80,6 +71,9 @@ namespace Umbraco.Web.Mvc /// protected UmbracoContext UmbracoContext => _umbracoContext ?? (_umbracoContext = UmbracoContext.Current); + // todo - try lazy property injection? + private FacadeRouter FacadeRouter => Core.DI.Current.Container.GetInstance(); + /// /// Exposes an UmbracoHelper /// @@ -96,10 +90,7 @@ namespace Umbraco.Web.Mvc return; } - UmbracoContext.Current.PublishedContentRequest = - new PublishedContentRequest( - UmbracoContext.Current.CleanedUmbracoUrl, UmbracoContext.Current.RoutingContext); - + UmbracoContext.Current.PublishedContentRequest = FacadeRouter.CreateRequest(UmbracoContext.Current); ConfigurePublishedContentRequest(UmbracoContext.Current.PublishedContentRequest, filterContext); } @@ -107,9 +98,9 @@ namespace Umbraco.Web.Mvc /// This assigns the published content to the request, developers can override this to specify /// any other custom attributes required. /// - /// + /// /// - protected virtual void ConfigurePublishedContentRequest(PublishedContentRequest pcr, ActionExecutedContext filterContext) + protected virtual void ConfigurePublishedContentRequest(PublishedContentRequest request, ActionExecutedContext filterContext) { if (_contentId.HasValue) { @@ -118,7 +109,7 @@ namespace Umbraco.Web.Mvc { throw new InvalidOperationException("Could not resolve content with id " + _contentId); } - pcr.PublishedContent = content; + request.PublishedContent = content; } else if (_dataTokenName.IsNullOrWhiteSpace() == false) { @@ -127,15 +118,14 @@ namespace Umbraco.Web.Mvc { throw new InvalidOperationException("No data token could be found with the name " + _dataTokenName); } - if ((result is IPublishedContent) == false) + if (result is IPublishedContent == false) { throw new InvalidOperationException("The data token resolved with name " + _dataTokenName + " was not an instance of " + typeof(IPublishedContent)); } - pcr.PublishedContent = (IPublishedContent) result; + request.PublishedContent = (IPublishedContent) result; } - pcr.Prepare(); + FacadeRouter.PrepareRequest(request); } - } } \ No newline at end of file diff --git a/src/Umbraco.Web/Mvc/RedirectToUmbracoPageResult.cs b/src/Umbraco.Web/Mvc/RedirectToUmbracoPageResult.cs index 70c325f227..25b2df51a3 100644 --- a/src/Umbraco.Web/Mvc/RedirectToUmbracoPageResult.cs +++ b/src/Umbraco.Web/Mvc/RedirectToUmbracoPageResult.cs @@ -31,7 +31,7 @@ namespace Umbraco.Web.Mvc throw new InvalidOperationException(string.Format("Cannot redirect, no entity was found for id {0}", _pageId)); } - var result = _umbracoContext.RoutingContext.UrlProvider.GetUrl(PublishedContent.Id); + var result = _umbracoContext.UrlProvider.GetUrl(PublishedContent.Id); if (result != "#") { _url = result; diff --git a/src/Umbraco.Web/Mvc/RenderMvcController.cs b/src/Umbraco.Web/Mvc/RenderMvcController.cs index afc8a76ac1..d7519683fb 100644 --- a/src/Umbraco.Web/Mvc/RenderMvcController.cs +++ b/src/Umbraco.Web/Mvc/RenderMvcController.cs @@ -26,7 +26,7 @@ namespace Umbraco.Web.Mvc /// /// Gets the Umbraco context. /// - public override UmbracoContext UmbracoContext => PublishedContentRequest.RoutingContext.UmbracoContext; + public override UmbracoContext UmbracoContext => PublishedContentRequest.UmbracoContext; /// /// Gets the current content item. diff --git a/src/Umbraco.Web/Mvc/RenderRouteHandler.cs b/src/Umbraco.Web/Mvc/RenderRouteHandler.cs index 74a9add44e..c98f4a554e 100644 --- a/src/Umbraco.Web/Mvc/RenderRouteHandler.cs +++ b/src/Umbraco.Web/Mvc/RenderRouteHandler.cs @@ -1,6 +1,5 @@ using System; using System.Linq; -using System.Text; using System.Web; using System.Web.Compilation; using System.Web.Mvc; @@ -8,11 +7,8 @@ using System.Web.Routing; using System.Web.SessionState; using Umbraco.Core; using Umbraco.Core.Logging; -using Umbraco.Core.Configuration; -using Umbraco.Core.Models; using Umbraco.Web.Models; using Umbraco.Web.Routing; -using umbraco.cms.businesslogic.template; using System.Collections.Generic; using Umbraco.Core.Plugins; @@ -28,36 +24,33 @@ namespace Umbraco.Web.Mvc internal const string Area = "ar"; } - public RenderRouteHandler(IControllerFactory controllerFactory) - { - if (controllerFactory == null) throw new ArgumentNullException("controllerFactory"); - _controllerFactory = controllerFactory; - } - - /// - /// Contructor generally used for unit testing - /// - /// - /// - internal RenderRouteHandler(IControllerFactory controllerFactory, UmbracoContext umbracoContext) - { - if (controllerFactory == null) throw new ArgumentNullException("controllerFactory"); - if (umbracoContext == null) throw new ArgumentNullException("umbracoContext"); - _controllerFactory = controllerFactory; - _umbracoContext = umbracoContext; - } - private readonly IControllerFactory _controllerFactory; + private readonly IUmbracoContextAccessor _umbracoContextAccessor; private readonly UmbracoContext _umbracoContext; - /// - /// Returns the current UmbracoContext - /// - public UmbracoContext UmbracoContext + // fixme - that one could / should accept a FacadeRouter (engine) to work on the FacadeRequest (published content request) + public RenderRouteHandler(IUmbracoContextAccessor umbracoContextAccessor, IControllerFactory controllerFactory) { - get { return _umbracoContext ?? UmbracoContext.Current; } + if (umbracoContextAccessor == null) throw new ArgumentNullException(nameof(umbracoContextAccessor)); + if (controllerFactory == null) throw new ArgumentNullException(nameof(controllerFactory)); + _umbracoContextAccessor = umbracoContextAccessor; + _controllerFactory = controllerFactory; } + // fixme - what about that one? + // called by TemplateRenderer - which is created in + // library - could get an engine without problem it's all ugly anyways + // UmbracoComponentRenderer - ?? that one is not so obvious + public RenderRouteHandler(UmbracoContext umbracoContext, IControllerFactory controllerFactory) + { + if (umbracoContext == null) throw new ArgumentNullException(nameof(umbracoContext)); + if (controllerFactory == null) throw new ArgumentNullException(nameof(controllerFactory)); + _umbracoContext = umbracoContext; + _controllerFactory = controllerFactory; + } + + private UmbracoContext UmbracoContext => _umbracoContext ?? _umbracoContextAccessor.UmbracoContext; + #region IRouteHandler Members /// @@ -72,18 +65,18 @@ namespace Umbraco.Web.Mvc { throw new NullReferenceException("There is not current UmbracoContext, it must be initialized before the RenderRouteHandler executes"); } - var docRequest = UmbracoContext.PublishedContentRequest; - if (docRequest == null) + var request = UmbracoContext.PublishedContentRequest; + if (request == null) { throw new NullReferenceException("There is not current PublishedContentRequest, it must be initialized before the RenderRouteHandler executes"); } SetupRouteDataForRequest( - new ContentModel(docRequest.PublishedContent), + new ContentModel(request.PublishedContent), requestContext, - docRequest); + request); - return GetHandlerForRoute(requestContext, docRequest); + return GetHandlerForRoute(requestContext, request); } @@ -94,19 +87,19 @@ namespace Umbraco.Web.Mvc /// /// /// - /// - internal void SetupRouteDataForRequest(ContentModel contentModel, RequestContext requestContext, PublishedContentRequest docRequest) + /// + internal void SetupRouteDataForRequest(ContentModel contentModel, RequestContext requestContext, PublishedContentRequest frequest) { //put essential data into the data tokens, the 'umbraco' key is required to be there for the view engine requestContext.RouteData.DataTokens.Add(Core.Constants.Web.UmbracoDataToken, contentModel); //required for the RenderModelBinder and view engine - requestContext.RouteData.DataTokens.Add(Core.Constants.Web.PublishedDocumentRequestDataToken, docRequest); //required for RenderMvcController - requestContext.RouteData.DataTokens.Add(Core.Constants.Web.UmbracoContextDataToken, UmbracoContext); //required for UmbracoTemplatePage + requestContext.RouteData.DataTokens.Add(Core.Constants.Web.PublishedDocumentRequestDataToken, frequest); //required for RenderMvcController + requestContext.RouteData.DataTokens.Add(Core.Constants.Web.UmbracoContextDataToken, UmbracoContext); //required for UmbracoViewPage } private void UpdateRouteDataForRequest(ContentModel contentModel, RequestContext requestContext) { - if (contentModel == null) throw new ArgumentNullException("contentModel"); - if (requestContext == null) throw new ArgumentNullException("requestContext"); + if (contentModel == null) throw new ArgumentNullException(nameof(contentModel)); + if (requestContext == null) throw new ArgumentNullException(nameof(requestContext)); requestContext.RouteData.DataTokens[Core.Constants.Web.UmbracoDataToken] = contentModel; // the rest should not change -- it's only the published content that has changed @@ -120,7 +113,7 @@ namespace Umbraco.Web.Mvc /// internal static PostedDataProxyInfo GetFormInfo(RequestContext requestContext) { - if (requestContext == null) throw new ArgumentNullException("requestContext"); + if (requestContext == null) throw new ArgumentNullException(nameof(requestContext)); //if it is a POST/GET then a value must be in the request if (requestContext.HttpContext.Request.QueryString["ufprt"].IsNullOrWhiteSpace() @@ -204,8 +197,8 @@ namespace Umbraco.Web.Mvc /// internal static IHttpHandler HandlePostedValues(RequestContext requestContext, PostedDataProxyInfo postedInfo) { - if (requestContext == null) throw new ArgumentNullException("requestContext"); - if (postedInfo == null) throw new ArgumentNullException("postedInfo"); + if (requestContext == null) throw new ArgumentNullException(nameof(requestContext)); + if (postedInfo == null) throw new ArgumentNullException(nameof(postedInfo)); //set the standard route values/tokens requestContext.RouteData.Values["controller"] = postedInfo.ControllerName; @@ -227,7 +220,7 @@ namespace Umbraco.Web.Mvc x.DataTokens.ContainsKey("area") == false).ToList(); // If more than one route is found, find one with a matching action - if (surfaceRoutes.Count() > 1) + if (surfaceRoutes.Count > 1) { surfaceRoute = surfaceRoutes.FirstOrDefault(x => x.Defaults["action"] != null && @@ -275,12 +268,12 @@ namespace Umbraco.Web.Mvc /// Returns a RouteDefinition object based on the current renderModel /// /// - /// + /// /// - internal virtual RouteDefinition GetUmbracoRouteDefinition(RequestContext requestContext, PublishedContentRequest publishedContentRequest) + internal virtual RouteDefinition GetUmbracoRouteDefinition(RequestContext requestContext, PublishedContentRequest request) { - if (requestContext == null) throw new ArgumentNullException("requestContext"); - if (publishedContentRequest == null) throw new ArgumentNullException("publishedContentRequest"); + if (requestContext == null) throw new ArgumentNullException(nameof(requestContext)); + if (request == null) throw new ArgumentNullException(nameof(request)); var defaultControllerType = Current.DefaultRenderMvcControllerType; var defaultControllerName = ControllerExtensions.GetControllerName(defaultControllerType); @@ -289,24 +282,24 @@ namespace Umbraco.Web.Mvc { ControllerName = defaultControllerName, ControllerType = defaultControllerType, - PublishedContentRequest = publishedContentRequest, + PublishedContentRequest = request, ActionName = ((Route)requestContext.RouteData.Route).Defaults["action"].ToString(), HasHijackedRoute = false }; //check that a template is defined), if it doesn't and there is a hijacked route it will just route // to the index Action - if (publishedContentRequest.HasTemplate) + if (request.HasTemplate) { //the template Alias should always be already saved with a safe name. //if there are hyphens in the name and there is a hijacked route, then the Action will need to be attributed // with the action name attribute. - var templateName = publishedContentRequest.TemplateAlias.Split('.')[0].ToSafeAlias(); + var templateName = request.TemplateAlias.Split('.')[0].ToSafeAlias(); def.ActionName = templateName; } //check if there's a custom controller assigned, base on the document type alias. - var controllerType = _controllerFactory.GetControllerTypeInternal(requestContext, publishedContentRequest.PublishedContent.DocumentTypeAlias); + var controllerType = _controllerFactory.GetControllerTypeInternal(requestContext, request.PublishedContent.DocumentTypeAlias); //check if that controller exists if (controllerType != null) @@ -327,7 +320,7 @@ namespace Umbraco.Web.Mvc { Current.Logger.Warn( "The current Document Type {0} matches a locally declared controller of type {1}. Custom Controllers for Umbraco routing must implement '{2}' and inherit from '{3}'.", - () => publishedContentRequest.PublishedContent.DocumentTypeAlias, + () => request.PublishedContent.DocumentTypeAlias, () => controllerType.FullName, () => typeof(IRenderController).FullName, () => typeof(ControllerBase).FullName); @@ -338,33 +331,33 @@ namespace Umbraco.Web.Mvc } //store the route definition - requestContext.RouteData.DataTokens[Umbraco.Core.Constants.Web.UmbracoRouteDefinitionDataToken] = def; + requestContext.RouteData.DataTokens[Core.Constants.Web.UmbracoRouteDefinitionDataToken] = def; return def; } - internal IHttpHandler GetHandlerOnMissingTemplate(PublishedContentRequest pcr) + internal IHttpHandler GetHandlerOnMissingTemplate(PublishedContentRequest request) { - if (pcr == null) throw new ArgumentNullException("pcr"); + if (request == null) throw new ArgumentNullException(nameof(request)); // missing template, so we're in a 404 here // so the content, if any, is a custom 404 page of some sort - if (!pcr.HasPublishedContent) + if (request.HasPublishedContent == false) // means the builder could not find a proper document to handle 404 return new PublishedContentNotFoundHandler(); - if (!pcr.HasTemplate) + if (request.HasTemplate == false) // means the engine could find a proper document, but the document has no template // at that point there isn't much we can do and there is no point returning // to Mvc since Mvc can't do much return new PublishedContentNotFoundHandler("In addition, no template exists to render the custom 404."); // so we have a template, so we should have a rendering engine - if (pcr.RenderingEngine == RenderingEngine.WebForms) // back to webforms ? + if (request.RenderingEngine == RenderingEngine.WebForms) // back to webforms ? return GetWebFormsHandler(); - if (pcr.RenderingEngine != RenderingEngine.Mvc) // else ? + if (request.RenderingEngine != RenderingEngine.Mvc) // else ? return new PublishedContentNotFoundHandler("In addition, no rendering engine exists to render the custom 404."); return null; @@ -374,13 +367,13 @@ namespace Umbraco.Web.Mvc /// this will determine the controller and set the values in the route data /// /// - /// - internal IHttpHandler GetHandlerForRoute(RequestContext requestContext, PublishedContentRequest publishedContentRequest) + /// + internal IHttpHandler GetHandlerForRoute(RequestContext requestContext, PublishedContentRequest request) { - if (requestContext == null) throw new ArgumentNullException("requestContext"); - if (publishedContentRequest == null) throw new ArgumentNullException("publishedContentRequest"); + if (requestContext == null) throw new ArgumentNullException(nameof(requestContext)); + if (request == null) throw new ArgumentNullException(nameof(request)); - var routeDef = GetUmbracoRouteDefinition(requestContext, publishedContentRequest); + var routeDef = GetUmbracoRouteDefinition(requestContext, request); //Need to check for a special case if there is form data being posted back to an Umbraco URL var postedInfo = GetFormInfo(requestContext); @@ -390,8 +383,8 @@ namespace Umbraco.Web.Mvc } //Now we can check if we are supposed to render WebForms when the route has not been hijacked - if (publishedContentRequest.RenderingEngine == RenderingEngine.WebForms - && publishedContentRequest.HasTemplate + if (request.RenderingEngine == RenderingEngine.WebForms + && request.HasTemplate && routeDef.HasHijackedRoute == false) { return GetWebFormsHandler(); @@ -399,16 +392,18 @@ namespace Umbraco.Web.Mvc //here we need to check if there is no hijacked route and no template assigned, if this is the case //we want to return a blank page, but we'll leave that up to the NoTemplateHandler. - if (!publishedContentRequest.HasTemplate && !routeDef.HasHijackedRoute) + if (request.HasTemplate == false && routeDef.HasHijackedRoute == false) { - publishedContentRequest.UpdateOnMissingTemplate(); // will go 404 + // fixme - better find a way to inject that engine? or at least Current.Engine of some sort! + var engine = Core.DI.Current.Container.GetInstance(); + request.UpdateOnMissingTemplate(); // request will go 404 // HandleHttpResponseStatus returns a value indicating that the request should // not be processed any further, eg because it has been redirect. then, exit. - if (UmbracoModule.HandleHttpResponseStatus(requestContext.HttpContext, publishedContentRequest, Current.Logger)) + if (UmbracoModule.HandleHttpResponseStatus(requestContext.HttpContext, request, Current.Logger)) return null; - var handler = GetHandlerOnMissingTemplate(publishedContentRequest); + var handler = GetHandlerOnMissingTemplate(request); // if it's not null it can be either the PublishedContentNotFoundHandler (no document was // found to handle 404, or document with no template was found) or the WebForms handler @@ -423,19 +418,17 @@ namespace Umbraco.Web.Mvc // else we are running Mvc // update the route data - because the PublishedContent has changed UpdateRouteDataForRequest( - new ContentModel(publishedContentRequest.PublishedContent), + new ContentModel(request.PublishedContent), requestContext); // update the route definition - routeDef = GetUmbracoRouteDefinition(requestContext, publishedContentRequest); + routeDef = GetUmbracoRouteDefinition(requestContext, request); } //no post values, just route to the controller/action requried (local) requestContext.RouteData.Values["controller"] = routeDef.ControllerName; - if (!string.IsNullOrWhiteSpace(routeDef.ActionName)) - { + if (string.IsNullOrWhiteSpace(routeDef.ActionName) == false) requestContext.RouteData.Values["action"] = routeDef.ActionName; - } // Set the session state requirements requestContext.HttpContext.SetSessionStateBehavior(GetSessionStateBehavior(requestContext, routeDef.ControllerName)); diff --git a/src/Umbraco.Web/Mvc/UmbracoVirtualNodeByIdRouteHandler.cs b/src/Umbraco.Web/Mvc/UmbracoVirtualNodeByIdRouteHandler.cs index 802b6cd199..f001f35b41 100644 --- a/src/Umbraco.Web/Mvc/UmbracoVirtualNodeByIdRouteHandler.cs +++ b/src/Umbraco.Web/Mvc/UmbracoVirtualNodeByIdRouteHandler.cs @@ -1,5 +1,4 @@ using System.Web.Routing; -using Umbraco.Core.Models; using Umbraco.Core.Models.PublishedContent; namespace Umbraco.Web.Mvc @@ -16,9 +15,7 @@ namespace Umbraco.Web.Mvc protected sealed override IPublishedContent FindContent(RequestContext requestContext, UmbracoContext umbracoContext) { var byId = umbracoContext.ContentCache.GetById(_realNodeId); - if (byId == null) return null; - - return FindContent(requestContext, umbracoContext, byId); + return byId == null ? null : FindContent(requestContext, umbracoContext, byId); } protected virtual IPublishedContent FindContent(RequestContext requestContext, UmbracoContext umbracoContext, IPublishedContent baseContent) diff --git a/src/Umbraco.Web/Mvc/UmbracoVirtualNodeRouteHandler.cs b/src/Umbraco.Web/Mvc/UmbracoVirtualNodeRouteHandler.cs index afd63f5094..9cf56ff298 100644 --- a/src/Umbraco.Web/Mvc/UmbracoVirtualNodeRouteHandler.cs +++ b/src/Umbraco.Web/Mvc/UmbracoVirtualNodeRouteHandler.cs @@ -1,11 +1,6 @@ -using System.Globalization; -using System.Linq; -using System.Web; +using System.Web; using System.Web.Mvc; using System.Web.Routing; -using System.Web.Security; -using Umbraco.Core.Configuration; -using Umbraco.Core.Models; using Umbraco.Core.Models.PublishedContent; using Umbraco.Web.Models; using Umbraco.Web.Routing; @@ -14,19 +9,19 @@ namespace Umbraco.Web.Mvc { public abstract class UmbracoVirtualNodeRouteHandler : IRouteHandler { + // todo - try lazy property injection? + private FacadeRouter FacadeRouter => Core.DI.Current.Container.GetInstance(); + public IHttpHandler GetHttpHandler(RequestContext requestContext) { var umbracoContext = UmbracoContext.Current; var found = FindContent(requestContext, umbracoContext); if (found == null) return new NotFoundHandler(); - - umbracoContext.PublishedContentRequest = new PublishedContentRequest( - umbracoContext.CleanedUmbracoUrl, umbracoContext.RoutingContext, - UmbracoConfig.For.UmbracoSettings().WebRouting, s => Roles.Provider.GetRolesForUser(s)) - { - PublishedContent = found - }; + + var request = FacadeRouter.CreateRequest(umbracoContext); + request.PublishedContent = found; + umbracoContext.PublishedContentRequest = request; //allows inheritors to change the pcr PreparePublishedContentRequest(umbracoContext.PublishedContentRequest); @@ -53,7 +48,7 @@ namespace Umbraco.Web.Mvc }; //set the special data token to the current route definition - requestContext.RouteData.DataTokens[Umbraco.Core.Constants.Web.UmbracoRouteDefinitionDataToken] = def; + requestContext.RouteData.DataTokens[Core.Constants.Web.UmbracoRouteDefinitionDataToken] = def; return RenderRouteHandler.HandlePostedValues(requestContext, formInfo); } @@ -63,9 +58,9 @@ namespace Umbraco.Web.Mvc protected abstract IPublishedContent FindContent(RequestContext requestContext, UmbracoContext umbracoContext); - protected virtual void PreparePublishedContentRequest(PublishedContentRequest publishedContentRequest) + protected virtual void PreparePublishedContentRequest(PublishedContentRequest request) { - publishedContentRequest.Prepare(); + FacadeRouter.PrepareRequest(request); } } } diff --git a/src/Umbraco.Web/Routing/ContentFinderByIdPath.cs b/src/Umbraco.Web/Routing/ContentFinderByIdPath.cs index 2fe1c64882..891b8d5c35 100644 --- a/src/Umbraco.Web/Routing/ContentFinderByIdPath.cs +++ b/src/Umbraco.Web/Routing/ContentFinderByIdPath.cs @@ -1,6 +1,4 @@ -using System; using Umbraco.Core.Logging; -using Umbraco.Core.Models; using Umbraco.Core; using Umbraco.Core.Configuration; using Umbraco.Core.Configuration.UmbracoSettings; @@ -33,35 +31,35 @@ namespace Umbraco.Web.Routing /// /// Tries to find and assign an Umbraco document to a PublishedContentRequest. /// - /// The PublishedContentRequest. + /// The PublishedContentRequest. /// A value indicating whether an Umbraco document was found and assigned. - public bool TryFindContent(PublishedContentRequest docRequest) + public bool TryFindContent(PublishedContentRequest frequest) { - if (docRequest.RoutingContext.UmbracoContext != null && docRequest.RoutingContext.UmbracoContext.InPreviewMode == false + if (frequest.UmbracoContext != null && frequest.UmbracoContext.InPreviewMode == false && _webRoutingSection.DisableFindContentByIdPath) return false; IPublishedContent node = null; - var path = docRequest.Uri.GetAbsolutePathDecoded(); + var path = frequest.Uri.GetAbsolutePathDecoded(); var nodeId = -1; if (path != "/") // no id if "/" { var noSlashPath = path.Substring(1); - if (!Int32.TryParse(noSlashPath, out nodeId)) + if (int.TryParse(noSlashPath, out nodeId) == false) nodeId = -1; if (nodeId > 0) { _logger.Debug("Id={0}", () => nodeId); - node = docRequest.RoutingContext.UmbracoContext.ContentCache.GetById(nodeId); + node = frequest.UmbracoContext.ContentCache.GetById(nodeId); if (node != null) { - docRequest.PublishedContent = node; - _logger.Debug("Found node with id={0}", () => docRequest.PublishedContent.Id); + frequest.PublishedContent = node; + _logger.Debug("Found node with id={0}", () => frequest.PublishedContent.Id); } else { diff --git a/src/Umbraco.Web/Routing/ContentFinderByLegacy404.cs b/src/Umbraco.Web/Routing/ContentFinderByLegacy404.cs index 46f992817e..a59fa2c6c7 100644 --- a/src/Umbraco.Web/Routing/ContentFinderByLegacy404.cs +++ b/src/Umbraco.Web/Routing/ContentFinderByLegacy404.cs @@ -28,33 +28,33 @@ namespace Umbraco.Web.Routing /// /// Tries to find and assign an Umbraco document to a PublishedContentRequest. /// - /// The PublishedContentRequest. + /// The PublishedContentRequest. /// A value indicating whether an Umbraco document was found and assigned. - public bool TryFindContent(PublishedContentRequest pcr) + public bool TryFindContent(PublishedContentRequest frequest) { _logger.Debug("Looking for a page to handle 404."); // try to find a culture as best as we can var errorCulture = CultureInfo.CurrentUICulture; - if (pcr.HasDomain) + if (frequest.HasDomain) { - errorCulture = pcr.Domain.Culture; + errorCulture = frequest.Domain.Culture; } else { - var route = pcr.Uri.GetAbsolutePathDecoded(); + var route = frequest.Uri.GetAbsolutePathDecoded(); var pos = route.LastIndexOf('/'); IPublishedContent node = null; while (pos > 1) { route = route.Substring(0, pos); - node = pcr.RoutingContext.UmbracoContext.ContentCache.GetByRoute(route); + node = frequest.UmbracoContext.ContentCache.GetByRoute(route); if (node != null) break; pos = route.LastIndexOf('/'); } if (node != null) { - var d = DomainHelper.FindWildcardDomainInPath(pcr.RoutingContext.UmbracoContext.Facade.DomainCache.GetAll(true), node.Path, null); + var d = DomainHelper.FindWildcardDomainInPath(frequest.UmbracoContext.Facade.DomainCache.GetAll(true), node.Path, null); if (d != null) errorCulture = d.Culture; } @@ -63,7 +63,7 @@ namespace Umbraco.Web.Routing var error404 = NotFoundHandlerHelper.GetCurrentNotFoundPageId( _contentConfigSection.Error404Collection.ToArray(), _entityService, - new PublishedContentQuery(pcr.RoutingContext.UmbracoContext.ContentCache, pcr.RoutingContext.UmbracoContext.MediaCache), + new PublishedContentQuery(frequest.UmbracoContext.ContentCache, frequest.UmbracoContext.MediaCache), errorCulture); IPublishedContent content = null; @@ -72,7 +72,7 @@ namespace Umbraco.Web.Routing { _logger.Debug("Got id={0}.", () => error404.Value); - content = pcr.RoutingContext.UmbracoContext.ContentCache.GetById(error404.Value); + content = frequest.UmbracoContext.ContentCache.GetById(error404.Value); _logger.Debug(content == null ? "Could not find content with that id." @@ -83,8 +83,8 @@ namespace Umbraco.Web.Routing _logger.Debug("Got nothing."); } - pcr.PublishedContent = content; - pcr.SetIs404(); + frequest.PublishedContent = content; + frequest.Is404 = true; return content != null; } } diff --git a/src/Umbraco.Web/Routing/ContentFinderByNiceUrl.cs b/src/Umbraco.Web/Routing/ContentFinderByNiceUrl.cs index f245e5e65d..a1edff6f2f 100644 --- a/src/Umbraco.Web/Routing/ContentFinderByNiceUrl.cs +++ b/src/Umbraco.Web/Routing/ContentFinderByNiceUrl.cs @@ -1,5 +1,4 @@ using Umbraco.Core.Logging; -using Umbraco.Core.Models; using Umbraco.Core; using Umbraco.Core.Models.PublishedContent; @@ -23,17 +22,17 @@ namespace Umbraco.Web.Routing /// /// Tries to find and assign an Umbraco document to a PublishedContentRequest. /// - /// The PublishedContentRequest. + /// The PublishedContentRequest. /// A value indicating whether an Umbraco document was found and assigned. - public virtual bool TryFindContent(PublishedContentRequest docRequest) + public virtual bool TryFindContent(PublishedContentRequest frequest) { string route; - if (docRequest.HasDomain) - route = docRequest.Domain.ContentId + DomainHelper.PathRelativeToDomain(docRequest.Domain.Uri, docRequest.Uri.GetAbsolutePathDecoded()); + if (frequest.HasDomain) + route = frequest.Domain.ContentId + DomainHelper.PathRelativeToDomain(frequest.Domain.Uri, frequest.Uri.GetAbsolutePathDecoded()); else - route = docRequest.Uri.GetAbsolutePathDecoded(); + route = frequest.Uri.GetAbsolutePathDecoded(); - var node = FindContent(docRequest, route); + var node = FindContent(frequest, route); return node != null; } @@ -47,7 +46,7 @@ namespace Umbraco.Web.Routing { Logger.Debug("Test route \"{0}\"", () => route); - var node = docreq.RoutingContext.UmbracoContext.ContentCache.GetByRoute(route); + var node = docreq.UmbracoContext.ContentCache.GetByRoute(route); if (node != null) { docreq.PublishedContent = node; diff --git a/src/Umbraco.Web/Routing/ContentFinderByNiceUrlAndTemplate.cs b/src/Umbraco.Web/Routing/ContentFinderByNiceUrlAndTemplate.cs index 9ef3cbd9c5..61bcbdb4fa 100644 --- a/src/Umbraco.Web/Routing/ContentFinderByNiceUrlAndTemplate.cs +++ b/src/Umbraco.Web/Routing/ContentFinderByNiceUrlAndTemplate.cs @@ -22,16 +22,16 @@ namespace Umbraco.Web.Routing /// /// Tries to find and assign an Umbraco document to a PublishedContentRequest. /// - /// The PublishedContentRequest. + /// The PublishedContentRequest. /// A value indicating whether an Umbraco document was found and assigned. /// If successful, also assigns the template. - public override bool TryFindContent(PublishedContentRequest docRequest) + public override bool TryFindContent(PublishedContentRequest frequest) { IPublishedContent node = null; - var path = docRequest.Uri.GetAbsolutePathDecoded(); + var path = frequest.Uri.GetAbsolutePathDecoded(); - if (docRequest.HasDomain) - path = DomainHelper.PathRelativeToDomain(docRequest.Domain.Uri, path); + if (frequest.HasDomain) + path = DomainHelper.PathRelativeToDomain(frequest.Domain.Uri, path); if (path != "/") // no template if "/" { @@ -44,11 +44,11 @@ namespace Umbraco.Web.Routing { Logger.Debug("Valid template: \"{0}\"", () => templateAlias); - var route = docRequest.HasDomain ? (docRequest.Domain.ContentId.ToString() + path) : path; - node = FindContent(docRequest, route); + var route = frequest.HasDomain ? (frequest.Domain.ContentId.ToString() + path) : path; + node = FindContent(frequest, route); if (UmbracoConfig.For.UmbracoSettings().WebRouting.DisableAlternativeTemplates == false && node != null) - docRequest.TemplateModel = template; + frequest.TemplateModel = template; } else { diff --git a/src/Umbraco.Web/Routing/ContentFinderByPageIdQuery.cs b/src/Umbraco.Web/Routing/ContentFinderByPageIdQuery.cs index b85aff7c5d..1d31a13d88 100644 --- a/src/Umbraco.Web/Routing/ContentFinderByPageIdQuery.cs +++ b/src/Umbraco.Web/Routing/ContentFinderByPageIdQuery.cs @@ -9,16 +9,16 @@ namespace Umbraco.Web.Routing /// public class ContentFinderByPageIdQuery : IContentFinder { - public bool TryFindContent(PublishedContentRequest docRequest) + public bool TryFindContent(PublishedContentRequest frequest) { int pageId; - if (int.TryParse(docRequest.RoutingContext.UmbracoContext.HttpContext.Request["umbPageID"], out pageId)) + if (int.TryParse(frequest.UmbracoContext.HttpContext.Request["umbPageID"], out pageId)) { - var doc = docRequest.RoutingContext.UmbracoContext.ContentCache.GetById(pageId); + var doc = frequest.UmbracoContext.ContentCache.GetById(pageId); if (doc != null) { - docRequest.PublishedContent = doc; + frequest.PublishedContent = doc; return true; } } diff --git a/src/Umbraco.Web/Routing/ContentFinderByProfile.cs b/src/Umbraco.Web/Routing/ContentFinderByProfile.cs index 5d9d0bdfbc..5e64751db2 100644 --- a/src/Umbraco.Web/Routing/ContentFinderByProfile.cs +++ b/src/Umbraco.Web/Routing/ContentFinderByProfile.cs @@ -1,6 +1,5 @@ using Umbraco.Core.Configuration; using Umbraco.Core.Logging; -using Umbraco.Core.Models; using Umbraco.Core; using Umbraco.Core.Models.PublishedContent; @@ -23,12 +22,12 @@ namespace Umbraco.Web.Routing /// /// Tries to find and assign an Umbraco document to a PublishedContentRequest. /// - /// The PublishedContentRequest. + /// The PublishedContentRequest. /// A value indicating whether an Umbraco document was found and assigned. - public override bool TryFindContent(PublishedContentRequest docRequest) + public override bool TryFindContent(PublishedContentRequest frequest) { IPublishedContent node = null; - var path = docRequest.Uri.GetAbsolutePathDecoded(); + var path = frequest.Uri.GetAbsolutePathDecoded(); var isProfile = false; var pos = path.LastIndexOf('/'); @@ -42,13 +41,13 @@ namespace Umbraco.Web.Routing isProfile = true; Logger.Debug("Path \"{0}\" is the profile path", () => path); - var route = docRequest.HasDomain ? (docRequest.Domain.ContentId + path) : path; - node = FindContent(docRequest, route); + var route = frequest.HasDomain ? (frequest.Domain.ContentId + path) : path; + node = FindContent(frequest, route); if (node != null) { //TODO: Should be handled by Context Items class manager (http://issues.umbraco.org/issue/U4-61) - docRequest.RoutingContext.UmbracoContext.HttpContext.Items["umbMemberLogin"] = memberLogin; + frequest.UmbracoContext.HttpContext.Items["umbMemberLogin"] = memberLogin; } else { diff --git a/src/Umbraco.Web/Routing/ContentFinderByRedirectUrl.cs b/src/Umbraco.Web/Routing/ContentFinderByRedirectUrl.cs index 0ad80e3ed0..9c9d921732 100644 --- a/src/Umbraco.Web/Routing/ContentFinderByRedirectUrl.cs +++ b/src/Umbraco.Web/Routing/ContentFinderByRedirectUrl.cs @@ -25,14 +25,14 @@ namespace Umbraco.Web.Routing /// /// Tries to find and assign an Umbraco document to a PublishedContentRequest. /// - /// The PublishedContentRequest. + /// The PublishedContentRequest. /// A value indicating whether an Umbraco document was found and assigned. /// Optionally, can also assign the template or anything else on the document request, although that is not required. - public bool TryFindContent(PublishedContentRequest contentRequest) + public bool TryFindContent(PublishedContentRequest frequest) { - var route = contentRequest.HasDomain - ? contentRequest.Domain.ContentId + DomainHelper.PathRelativeToDomain(contentRequest.Domain.Uri, contentRequest.Uri.GetAbsolutePathDecoded()) - : contentRequest.Uri.GetAbsolutePathDecoded(); + var route = frequest.HasDomain + ? frequest.Domain.ContentId + DomainHelper.PathRelativeToDomain(frequest.Domain.Uri, frequest.Uri.GetAbsolutePathDecoded()) + : frequest.Uri.GetAbsolutePathDecoded(); var redirectUrl = _redirectUrlService.GetMostRecentRedirectUrl(route); @@ -42,7 +42,7 @@ namespace Umbraco.Web.Routing return false; } - var content = contentRequest.RoutingContext.UmbracoContext.ContentCache.GetById(redirectUrl.ContentId); + var content = frequest.UmbracoContext.ContentCache.GetById(redirectUrl.ContentId); var url = content == null ? "#" : content.Url; if (url.StartsWith("#")) { @@ -53,7 +53,7 @@ namespace Umbraco.Web.Routing _logger.Debug("Route \"{0}\" matches content {1} with url \"{2}\", redirecting.", () => route, () => content.Id, () => url); - contentRequest.SetRedirectPermanent(url); + frequest.SetRedirectPermanent(url); return true; } } diff --git a/src/Umbraco.Web/Routing/ContentFinderByUrlAlias.cs b/src/Umbraco.Web/Routing/ContentFinderByUrlAlias.cs index 685e3a792e..30d05fa1a9 100644 --- a/src/Umbraco.Web/Routing/ContentFinderByUrlAlias.cs +++ b/src/Umbraco.Web/Routing/ContentFinderByUrlAlias.cs @@ -2,7 +2,6 @@ using System; using System.Text; using System.Linq; using Umbraco.Core.Logging; -using Umbraco.Core.Models; using Umbraco.Core; using Umbraco.Core.Models.PublishedContent; using Umbraco.Core.Xml; @@ -29,22 +28,22 @@ namespace Umbraco.Web.Routing /// /// Tries to find and assign an Umbraco document to a PublishedContentRequest. /// - /// The PublishedContentRequest. + /// The PublishedContentRequest. /// A value indicating whether an Umbraco document was found and assigned. - public bool TryFindContent(PublishedContentRequest docRequest) + public bool TryFindContent(PublishedContentRequest frequest) { IPublishedContent node = null; - if (docRequest.Uri.AbsolutePath != "/") // no alias if "/" + if (frequest.Uri.AbsolutePath != "/") // no alias if "/" { - node = FindContentByAlias(docRequest.RoutingContext.UmbracoContext.ContentCache, - docRequest.HasDomain ? docRequest.Domain.ContentId : 0, - docRequest.Uri.GetAbsolutePathDecoded()); + node = FindContentByAlias(frequest.UmbracoContext.ContentCache, + frequest.HasDomain ? frequest.Domain.ContentId : 0, + frequest.Uri.GetAbsolutePathDecoded()); if (node != null) { - docRequest.PublishedContent = node; - Logger.Debug("Path \"{0}\" is an alias for id={1}", () => docRequest.Uri.AbsolutePath, () => docRequest.PublishedContent.Id); + frequest.PublishedContent = node; + Logger.Debug("Path \"{0}\" is an alias for id={1}", () => frequest.Uri.AbsolutePath, () => frequest.PublishedContent.Id); } } diff --git a/src/Umbraco.Web/Routing/PublishedContentRequestEngine.cs b/src/Umbraco.Web/Routing/FacadeRouter.cs similarity index 53% rename from src/Umbraco.Web/Routing/PublishedContentRequestEngine.cs rename to src/Umbraco.Web/Routing/FacadeRouter.cs index ba7b717ff1..3831458c9f 100644 --- a/src/Umbraco.Web/Routing/PublishedContentRequestEngine.cs +++ b/src/Umbraco.Web/Routing/FacadeRouter.cs @@ -1,698 +1,723 @@ -using System; -using System.Linq; -using System.Threading; -using System.Globalization; -using System.IO; -using Umbraco.Core; -using Umbraco.Core.Configuration.UmbracoSettings; -using Umbraco.Core.IO; -using Umbraco.Core.Logging; -using umbraco; -using Umbraco.Core.Services; -using Umbraco.Web.Security; -using RenderingEngine = Umbraco.Core.RenderingEngine; - -namespace Umbraco.Web.Routing -{ - internal class PublishedContentRequestEngine - { - private readonly PublishedContentRequest _pcr; - private readonly RoutingContext _routingContext; - private readonly IWebRoutingSection _webRoutingSection; - - /// - /// Initializes a new instance of the class with a content request. - /// - /// - /// The content request. - public PublishedContentRequestEngine( - IWebRoutingSection webRoutingSection, - PublishedContentRequest pcr) - { - if (pcr == null) throw new ArgumentException("pcr is null."); - if (webRoutingSection == null) throw new ArgumentNullException(nameof(webRoutingSection)); - - _pcr = pcr; - _webRoutingSection = webRoutingSection; - - _routingContext = pcr.RoutingContext; - if (_routingContext == null) throw new ArgumentException("pcr.RoutingContext is null."); - - var umbracoContext = _routingContext.UmbracoContext; - if (umbracoContext == null) throw new ArgumentException("pcr.RoutingContext.UmbracoContext is null."); - if (umbracoContext.RoutingContext != _routingContext) throw new ArgumentException("RoutingContext confusion."); - // no! not set yet. - //if (umbracoContext.PublishedContentRequest != _pcr) throw new ArgumentException("PublishedContentRequest confusion."); - } - - protected ProfilingLogger ProfilingLogger => Current.ProfilingLogger; // fixme inject - - protected ServiceContext Services => Current.Services; // fixme inject - - #region Public - - /// - /// Prepares the request. - /// - /// - /// Returns false if the request was not successfully prepared - /// - public bool PrepareRequest() - { - // note - at that point the original legacy module did something do handle IIS custom 404 errors - // ie pages looking like /anything.aspx?404;/path/to/document - I guess the reason was to support - // "directory urls" without having to do wildcard mapping to ASP.NET on old IIS. This is a pain - // to maintain and probably not used anymore - removed as of 06/2012. @zpqrtbnk. - // - // to trigger Umbraco's not-found, one should configure IIS and/or ASP.NET custom 404 errors - // so that they point to a non-existing page eg /redirect-404.aspx - // TODO: SD: We need more information on this for when we release 4.10.0 as I'm not sure what this means. - - // trigger the Preparing event - at that point anything can still be changed - // the idea is that it is possible to change the uri - // - _pcr.OnPreparing(); - - //find domain - FindDomain(); - - // if request has been flagged to redirect then return - // whoever called us is in charge of actually redirecting - if (_pcr.IsRedirect) - { - return false; - } - - // set the culture on the thread - once, so it's set when running document lookups - Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture = _pcr.Culture; - - //find the published content if it's not assigned. This could be manually assigned with a custom route handler, or - // with something like EnsurePublishedContentRequestAttribute or UmbracoVirtualNodeRouteHandler. Those in turn call this method - // to setup the rest of the pipeline but we don't want to run the finders since there's one assigned. - if (_pcr.PublishedContent == null) - { - // find the document & template - FindPublishedContentAndTemplate(); - } - - // handle wildcard domains - HandleWildcardDomains(); - - // set the culture on the thread -- again, 'cos it might have changed due to a finder or wildcard domain - Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture = _pcr.Culture; - - // trigger the Prepared event - at that point it is still possible to change about anything - // even though the request might be flagged for redirection - we'll redirect _after_ the event - // - // also, OnPrepared() will make the PublishedContentRequest readonly, so nothing can change - // - _pcr.OnPrepared(); - - // we don't take care of anything so if the content has changed, it's up to the user - // to find out the appropriate template - - //complete the PCR and assign the remaining values - return ConfigureRequest(); - } - - /// - /// Called by PrepareRequest once everything has been discovered, resolved and assigned to the PCR. This method - /// finalizes the PCR with the values assigned. - /// - /// - /// Returns false if the request was not successfully configured - /// - /// - /// This method logic has been put into it's own method in case developers have created a custom PCR or are assigning their own values - /// but need to finalize it themselves. - /// - public bool ConfigureRequest() - { - if (_pcr.HasPublishedContent == false) - { - return false; - } - - // set the culture on the thread -- again, 'cos it might have changed in the event handler - Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture = _pcr.Culture; - - // if request has been flagged to redirect, or has no content to display, - // then return - whoever called us is in charge of actually redirecting - if (_pcr.IsRedirect || _pcr.HasPublishedContent == false) - { - return false; - } - - // we may be 404 _and_ have a content - - // can't go beyond that point without a PublishedContent to render - // it's ok not to have a template, in order to give MVC a chance to hijack routes - - // note - the page() ctor below will cause the "page" to get the value of all its - // "elements" ie of all the IPublishedContent property. If we use the object value, - // that will trigger macro execution - which can't happen because macro execution - // requires that _pcr.UmbracoPage is already initialized = catch-22. The "legacy" - // pipeline did _not_ evaluate the macros, ie it is using the data value, and we - // have to keep doing it because of that catch-22. - - // assign the legacy page back to the docrequest - // handlers like default.aspx will want it and most macros currently need it - _pcr.UmbracoPage = new page(_pcr); - - // used by many legacy objects - _routingContext.UmbracoContext.HttpContext.Items["pageID"] = _pcr.PublishedContent.Id; - _routingContext.UmbracoContext.HttpContext.Items["pageElements"] = _pcr.UmbracoPage.Elements; - - return true; - } - - /// - /// Updates the request when there is no template to render the content. - /// - /// This is called from Mvc when there's a document to render but no template. - public void UpdateRequestOnMissingTemplate() - { - // clear content - var content = _pcr.PublishedContent; - _pcr.PublishedContent = null; - - HandlePublishedContent(); // will go 404 - FindTemplate(); - - // if request has been flagged to redirect then return - // whoever called us is in charge of redirecting - if (_pcr.IsRedirect) - return; - - if (_pcr.HasPublishedContent == false) - { - // means the engine could not find a proper document to handle 404 - // restore the saved content so we know it exists - _pcr.PublishedContent = content; - return; - } - - if (_pcr.HasTemplate == false) - { - // means we may have a document, but we have no template - // at that point there isn't much we can do and there is no point returning - // to Mvc since Mvc can't do much either - return; - } - - // see note in PrepareRequest() - - // assign the legacy page back to the docrequest - // handlers like default.aspx will want it and most macros currently need it - _pcr.UmbracoPage = new page(_pcr); - - // these two are used by many legacy objects - _routingContext.UmbracoContext.HttpContext.Items["pageID"] = _pcr.PublishedContent.Id; - _routingContext.UmbracoContext.HttpContext.Items["pageElements"] = _pcr.UmbracoPage.Elements; - } - - #endregion - - #region Domain - - /// - /// Finds the site root (if any) matching the http request, and updates the PublishedContentRequest accordingly. - /// - /// A value indicating whether a domain was found. - internal bool FindDomain() - { - const string tracePrefix = "FindDomain: "; - - // note - we are not handling schemes nor ports here. - - ProfilingLogger.Logger.Debug("{0}Uri=\"{1}\"", () => tracePrefix, () => _pcr.Uri); - - // try to find a domain matching the current request - var domainCache = _routingContext.UmbracoContext.Facade.DomainCache; - var domainAndUri = DomainHelper.DomainForUri(domainCache.GetAll(false), _pcr.Uri); - - // handle domain - always has a contentId and a culture - if (domainAndUri != null) - { - // matching an existing domain - ProfilingLogger.Logger.Debug("{0}Matches domain=\"{1}\", rootId={2}, culture=\"{3}\"", - () => tracePrefix, - () => domainAndUri.Name, - () => domainAndUri.ContentId, - () => domainAndUri.Culture); - - _pcr.Domain = domainAndUri; - _pcr.Culture = domainAndUri.Culture; - - // canonical? not implemented at the moment - // if (...) - // { - // _pcr.RedirectUrl = "..."; - // return true; - // } - } - else - { - // not matching any existing domain - ProfilingLogger.Logger.Debug("{0}Matches no domain", () => tracePrefix); - - var defaultLanguage = Services.LocalizationService.GetAllLanguages().FirstOrDefault(); - _pcr.Culture = defaultLanguage == null ? CultureInfo.CurrentUICulture : new CultureInfo(defaultLanguage.IsoCode); - } - - ProfilingLogger.Logger.Debug("{0}Culture=\"{1}\"", () => tracePrefix, () => _pcr.Culture.Name); - - return _pcr.Domain != null; - } - - /// - /// Looks for wildcard domains in the path and updates Culture accordingly. - /// - internal void HandleWildcardDomains() - { - const string tracePrefix = "HandleWildcardDomains: "; - - if (_pcr.HasPublishedContent == false) - return; - - var nodePath = _pcr.PublishedContent.Path; - ProfilingLogger.Logger.Debug("{0}Path=\"{1}\"", () => tracePrefix, () => nodePath); - var rootNodeId = _pcr.HasDomain ? _pcr.Domain.ContentId : (int?)null; - var domainCache = _routingContext.UmbracoContext.Facade.DomainCache; - var domain = DomainHelper.FindWildcardDomainInPath(domainCache.GetAll(true), nodePath, rootNodeId); - - // always has a contentId and a culture - if (domain != null) - { - _pcr.Culture = domain.Culture; - ProfilingLogger.Logger.Debug("{0}Got domain on node {1}, set culture to \"{2}\".", () => tracePrefix, - () => domain.ContentId, () => _pcr.Culture.Name); - } - else - { - ProfilingLogger.Logger.Debug("{0}No match.", () => tracePrefix); - } - } - - #endregion - - #region Rendering engine - - /// - /// Finds the rendering engine to use to render a template specified by its alias. - /// - /// The alias of the template. - /// The rendering engine, or Unknown if the template was not found. - internal RenderingEngine FindTemplateRenderingEngine(string alias) - { - if (string.IsNullOrWhiteSpace(alias)) - return RenderingEngine.Unknown; - - alias = alias.Replace('\\', '/'); // forward slashes only - - // NOTE: we could start with what's the current default? - - if (FindTemplateRenderingEngineInDirectory(new DirectoryInfo(IOHelper.MapPath(SystemDirectories.MvcViews)), - alias, new[] { ".cshtml", ".vbhtml" })) - return RenderingEngine.Mvc; - - if (FindTemplateRenderingEngineInDirectory(new DirectoryInfo(IOHelper.MapPath(SystemDirectories.Masterpages)), - alias, new[] { ".master" })) - return RenderingEngine.WebForms; - - return RenderingEngine.Unknown; - } - - internal bool FindTemplateRenderingEngineInDirectory(DirectoryInfo directory, string alias, string[] extensions) - { - if (directory == null || directory.Exists == false) - return false; - - var pos = alias.IndexOf('/'); - if (pos > 0) - { - // recurse - var subdir = directory.GetDirectories(alias.Substring(0, pos)).FirstOrDefault(); - alias = alias.Substring(pos + 1); - return subdir != null && FindTemplateRenderingEngineInDirectory(subdir, alias, extensions); - } - - // look here - return directory.GetFiles().Any(f => extensions.Any(e => f.Name.InvariantEquals(alias + e))); - } - - #endregion - - #region Document and template - - /// - /// Finds the Umbraco document (if any) matching the request, and updates the PublishedContentRequest accordingly. - /// - /// A value indicating whether a document and template were found. - private void FindPublishedContentAndTemplate() - { - const string tracePrefix = "FindPublishedContentAndTemplate: "; - ProfilingLogger.Logger.Debug("{0}Path=\"{1}\"", () => tracePrefix, () => _pcr.Uri.AbsolutePath); - - // run the document finders - FindPublishedContent(); - - // if request has been flagged to redirect then return - // whoever called us is in charge of actually redirecting - // -- do not process anything any further -- - if (_pcr.IsRedirect) - return; - - // not handling umbracoRedirect here but after LookupDocument2 - // so internal redirect, 404, etc has precedence over redirect - - // handle not-found, redirects, access... - HandlePublishedContent(); - - // find a template - FindTemplate(); - - // handle umbracoRedirect - FollowExternalRedirect(); - } - - /// - /// Tries to find the document matching the request, by running the IPublishedContentFinder instances. - /// - /// There is no finder collection. - internal void FindPublishedContent() - { - const string tracePrefix = "FindPublishedContent: "; - - // look for the document - // the first successful finder, if any, will set this.PublishedContent, and may also set this.Template - // some finders may implement caching - - using (ProfilingLogger.DebugDuration( - $"{tracePrefix}Begin finders", - $"{tracePrefix}End finders, {(_pcr.HasPublishedContent ? "a document was found" : "no document was found")}")) - { - if (_routingContext.PublishedContentFinders == null) - throw new InvalidOperationException("There is no finder collection."); - - //iterate but return on first one that finds it - var found = _routingContext.PublishedContentFinders.Any(finder => - { - Current.Logger.Debug("Finder " + finder.GetType().FullName); - return finder.TryFindContent(_pcr); - }); - } - - // indicate that the published content (if any) we have at the moment is the - // one that was found by the standard finders before anything else took place. - _pcr.SetIsInitialPublishedContent(); - } - - /// - /// Handles the published content (if any). - /// - /// - /// Handles "not found", internal redirects, access validation... - /// things that must be handled in one place because they can create loops - /// - private void HandlePublishedContent() - { - const string tracePrefix = "HandlePublishedContent: "; - - // because these might loop, we have to have some sort of infinite loop detection - int i = 0, j = 0; - const int maxLoop = 8; - do - { - ProfilingLogger.Logger.Debug("{0}{1}", () => tracePrefix, () => (i == 0 ? "Begin" : "Loop")); - - // handle not found - if (_pcr.HasPublishedContent == false) - { - _pcr.Is404 = true; - ProfilingLogger.Logger.Debug("{0}No document, try last chance lookup", () => tracePrefix); - - // if it fails then give up, there isn't much more that we can do - var lastChance = _routingContext.PublishedContentLastChanceFinder; - if (lastChance == null || lastChance.TryFindContent(_pcr) == false) - { - ProfilingLogger.Logger.Debug("{0}Failed to find a document, give up", () => tracePrefix); - break; - } - - ProfilingLogger.Logger.Debug("{0}Found a document", () => tracePrefix); - } - - // follow internal redirects as long as it's not running out of control ie infinite loop of some sort - j = 0; - while (FollowInternalRedirects() && j++ < maxLoop) - { } - if (j == maxLoop) // we're running out of control - break; - - // ensure access - if (_pcr.HasPublishedContent) - EnsurePublishedContentAccess(); - - // loop while we don't have page, ie the redirect or access - // got us to nowhere and now we need to run the notFoundLookup again - // as long as it's not running out of control ie infinite loop of some sort - - } while (_pcr.HasPublishedContent == false && i++ < maxLoop); - - if (i == maxLoop || j == maxLoop) - { - ProfilingLogger.Logger.Debug("{0}Looks like we're running into an infinite loop, abort", () => tracePrefix); - _pcr.PublishedContent = null; - } - - ProfilingLogger.Logger.Debug("{0}End", () => tracePrefix); - } - - /// - /// Follows internal redirections through the umbracoInternalRedirectId document property. - /// - /// A value indicating whether redirection took place and led to a new published document. - /// - /// Redirecting to a different site root and/or culture will not pick the new site root nor the new culture. - /// As per legacy, if the redirect does not work, we just ignore it. - /// - private bool FollowInternalRedirects() - { - const string tracePrefix = "FollowInternalRedirects: "; - - if (_pcr.PublishedContent == null) - throw new InvalidOperationException("There is no PublishedContent."); - - var redirect = false; - var internalRedirect = _pcr.PublishedContent.Value(Constants.Conventions.Content.InternalRedirectId); - - if (string.IsNullOrWhiteSpace(internalRedirect)) - return false; - - ProfilingLogger.Logger.Debug("{0}Found umbracoInternalRedirectId={1}", () => tracePrefix, () => internalRedirect); - - int internalRedirectId; - if (int.TryParse(internalRedirect, out internalRedirectId) == false) - internalRedirectId = -1; - - if (internalRedirectId <= 0) - { - // bad redirect - log and display the current page (legacy behavior) - //_pcr.Document = null; // no! that would be to force a 404 - ProfilingLogger.Logger.Debug("{0}Failed to redirect to id={1}: invalid value", () => tracePrefix, () => internalRedirect); - } - else if (internalRedirectId == _pcr.PublishedContent.Id) - { - // redirect to self - ProfilingLogger.Logger.Debug("{0}Redirecting to self, ignore", () => tracePrefix); - } - else - { - // redirect to another page - var node = _routingContext.UmbracoContext.ContentCache.GetById(internalRedirectId); - - if (node != null) - { - _pcr.SetInternalRedirectPublishedContent(node); // don't use .PublishedContent here - redirect = true; - ProfilingLogger.Logger.Debug("{0}Redirecting to id={1}", () => tracePrefix, () => internalRedirectId); - } - else - { - ProfilingLogger.Logger.Debug("{0}Failed to redirect to id={1}: no such published document", () => tracePrefix, () => internalRedirectId); - } - } - - return redirect; - } - - /// - /// Ensures that access to current node is permitted. - /// - /// Redirecting to a different site root and/or culture will not pick the new site root nor the new culture. - private void EnsurePublishedContentAccess() - { - const string tracePrefix = "EnsurePublishedContentAccess: "; - - if (_pcr.PublishedContent == null) - throw new InvalidOperationException("There is no PublishedContent."); - - var path = _pcr.PublishedContent.Path; - - var publicAccessAttempt = Services.PublicAccessService.IsProtected(path); - - if (publicAccessAttempt) - { - ProfilingLogger.Logger.Debug("{0}Page is protected, check for access", () => tracePrefix); - - var membershipHelper = new MembershipHelper(_routingContext.UmbracoContext); - - if (membershipHelper.IsLoggedIn() == false) - { - ProfilingLogger.Logger.Debug("{0}Not logged in, redirect to login page", () => tracePrefix); - - var loginPageId = publicAccessAttempt.Result.LoginNodeId; - - if (loginPageId != _pcr.PublishedContent.Id) - _pcr.PublishedContent = _routingContext.UmbracoContext.ContentCache.GetById(loginPageId); - } - else if (Services.PublicAccessService.HasAccess(_pcr.PublishedContent.Id, Services.ContentService, _pcr.GetRolesForLogin(membershipHelper.CurrentUserName)) == false) - { - ProfilingLogger.Logger.Debug("{0}Current member has not access, redirect to error page", () => tracePrefix); - var errorPageId = publicAccessAttempt.Result.NoAccessNodeId; - if (errorPageId != _pcr.PublishedContent.Id) - _pcr.PublishedContent = _routingContext.UmbracoContext.ContentCache.GetById(errorPageId); - } - else - { - ProfilingLogger.Logger.Debug("{0}Current member has access", () => tracePrefix); - } - } - else - { - ProfilingLogger.Logger.Debug("{0}Page is not protected", () => tracePrefix); - } - } - - /// - /// Finds a template for the current node, if any. - /// - private void FindTemplate() - { - // NOTE: at the moment there is only 1 way to find a template, and then ppl must - // use the Prepared event to change the template if they wish. Should we also - // implement an ITemplateFinder logic? - - const string tracePrefix = "FindTemplate: "; - - if (_pcr.PublishedContent == null) - { - _pcr.TemplateModel = null; - return; - } - - // read the alternate template alias, from querystring, form, cookie or server vars, - // only if the published content is the initial once, else the alternate template - // does not apply - // + optionnally, apply the alternate template on internal redirects - var useAltTemplate = _webRoutingSection.DisableAlternativeTemplates == false - && (_pcr.IsInitialPublishedContent - || (_webRoutingSection.InternalRedirectPreservesTemplate && _pcr.IsInternalRedirectPublishedContent)); - var altTemplate = useAltTemplate - ? _routingContext.UmbracoContext.HttpContext.Request[Constants.Conventions.Url.AltTemplate] - : null; - - if (string.IsNullOrWhiteSpace(altTemplate)) - { - // we don't have an alternate template specified. use the current one if there's one already, - // which can happen if a content lookup also set the template (LookupByNiceUrlAndTemplate...), - // else lookup the template id on the document then lookup the template with that id. - - if (_pcr.HasTemplate) - { - ProfilingLogger.Logger.Debug("{0}Has a template already, and no alternate template.", () => tracePrefix); - return; - } - - // TODO: When we remove the need for a database for templates, then this id should be irrelavent, - // not sure how were going to do this nicely. - - var templateId = _pcr.PublishedContent.TemplateId; - - if (templateId > 0) - { - ProfilingLogger.Logger.Debug("{0}Look for template id={1}", () => tracePrefix, () => templateId); - var template = Current.Services.FileService.GetTemplate(templateId); - if (template == null) - throw new InvalidOperationException("The template with Id " + templateId + " does not exist, the page cannot render"); - _pcr.TemplateModel = template; - ProfilingLogger.Logger.Debug("{0}Got template id={1} alias=\"{2}\"", () => tracePrefix, () => template.Id, () => template.Alias); - } - else - { - ProfilingLogger.Logger.Debug("{0}No specified template.", () => tracePrefix); - } - } - else - { - // we have an alternate template specified. lookup the template with that alias - // this means the we override any template that a content lookup might have set - // so /path/to/page/template1?altTemplate=template2 will use template2 - - // ignore if the alias does not match - just trace - - if (_pcr.HasTemplate) - ProfilingLogger.Logger.Debug("{0}Has a template already, but also an alternate template.", () => tracePrefix); - ProfilingLogger.Logger.Debug("{0}Look for alternate template alias=\"{1}\"", () => tracePrefix, () => altTemplate); - - var template = Current.Services.FileService.GetTemplate(altTemplate); - if (template != null) - { - _pcr.TemplateModel = template; - ProfilingLogger.Logger.Debug("{0}Got template id={1} alias=\"{2}\"", () => tracePrefix, () => template.Id, () => template.Alias); - } - else - { - ProfilingLogger.Logger.Debug("{0}The template with alias=\"{1}\" does not exist, ignoring.", () => tracePrefix, () => altTemplate); - } - } - - if (_pcr.HasTemplate == false) - { - ProfilingLogger.Logger.Debug("{0}No template was found.", () => tracePrefix); - - // initial idea was: if we're not already 404 and UmbracoSettings.HandleMissingTemplateAs404 is true - // then reset _pcr.Document to null to force a 404. - // - // but: because we want to let MVC hijack routes even though no template is defined, we decide that - // a missing template is OK but the request will then be forwarded to MVC, which will need to take - // care of everything. - // - // so, don't set _pcr.Document to null here - } - else - { - ProfilingLogger.Logger.Debug("{0}Running with template id={1} alias=\"{2}\"", () => tracePrefix, () => _pcr.TemplateModel.Id, () => _pcr.TemplateModel.Alias); - } - } - - /// - /// Follows external redirection through umbracoRedirect document property. - /// - /// As per legacy, if the redirect does not work, we just ignore it. - private void FollowExternalRedirect() - { - if (_pcr.HasPublishedContent == false) return; - - var redirectId = _pcr.PublishedContent.Value(Constants.Conventions.Content.Redirect, -1); - var redirectUrl = "#"; - if (redirectId > 0) - redirectUrl = _routingContext.UrlProvider.GetUrl(redirectId); - if (redirectUrl != "#") - _pcr.SetRedirect(redirectUrl); - } - - #endregion - } -} +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Globalization; +using System.IO; +using umbraco; +using Umbraco.Core; +using Umbraco.Core.Configuration.UmbracoSettings; +using Umbraco.Core.IO; +using Umbraco.Core.Logging; +using Umbraco.Core.Models; +using Umbraco.Core.Services; +using Umbraco.Web.Security; +using RenderingEngine = Umbraco.Core.RenderingEngine; + +namespace Umbraco.Web.Routing +{ + // this provides the logic to published content requests + // there is only one instance of this class and it has all + // the dependencies injected + + internal class FacadeRouter + { + // fixme - coupling PublishedContentRequest & PublishedContentRequestEngine + // is bad + // could be entirely stateless! and unique! or merged into the request entirely! + // depends on whether we want the request to be a simple DTO = yes + + // fixme - maybe we should be initialized with UmbracoContext accessor instead? + + private readonly IWebRoutingSection _webRoutingSection; + private readonly IEnumerable _contentFinders; + private readonly IContentLastChanceFinder _contentLastChanceFinder; + private readonly ServiceContext _services; + private readonly ProfilingLogger _profilingLogger; + private readonly ILogger _logger; + + /// + /// Initializes a new instance of the class. + /// + public FacadeRouter( + IWebRoutingSection webRoutingSection, + IEnumerable contentFinders, + IContentLastChanceFinder contentLastChanceFinder, + ServiceContext services, + ProfilingLogger proflog) + { + if (webRoutingSection == null) throw new ArgumentNullException(nameof(webRoutingSection)); // fixme usage? + + if (contentFinders == null) throw new ArgumentNullException(nameof(contentFinders)); + if (contentLastChanceFinder == null) throw new ArgumentNullException(nameof(contentLastChanceFinder)); + if (services == null) throw new ArgumentNullException(nameof(services)); + if (proflog == null) throw new ArgumentNullException(nameof(proflog)); + _webRoutingSection = webRoutingSection; + _contentFinders = contentFinders; + _contentLastChanceFinder = contentLastChanceFinder; + _services = services; + _profilingLogger = proflog; + _logger = proflog.Logger; + } + + // fixme + private Func> GetRolesForLogin; + + public PublishedContentRequest CreateRequest(UmbracoContext umbracoContext, Uri uri = null) + { + return new PublishedContentRequest(this, umbracoContext, uri ?? umbracoContext.CleanedUmbracoUrl); + } + + #region Request + + /// + /// Prepares the request. + /// + /// + /// Returns false if the request was not successfully prepared + /// + public bool PrepareRequest(PublishedContentRequest request) + { + // note - at that point the original legacy module did something do handle IIS custom 404 errors + // ie pages looking like /anything.aspx?404;/path/to/document - I guess the reason was to support + // "directory urls" without having to do wildcard mapping to ASP.NET on old IIS. This is a pain + // to maintain and probably not used anymore - removed as of 06/2012. @zpqrtbnk. + // + // to trigger Umbraco's not-found, one should configure IIS and/or ASP.NET custom 404 errors + // so that they point to a non-existing page eg /redirect-404.aspx + // TODO: SD: We need more information on this for when we release 4.10.0 as I'm not sure what this means. + + // trigger the Preparing event - at that point anything can still be changed + // the idea is that it is possible to change the uri + // + request.OnPreparing(); + + //find domain + FindDomain(request); + + // if request has been flagged to redirect then return + // whoever called us is in charge of actually redirecting + if (request.IsRedirect) + { + return false; + } + + // set the culture on the thread - once, so it's set when running document lookups + Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture = request.Culture; + + //find the published content if it's not assigned. This could be manually assigned with a custom route handler, or + // with something like EnsurePublishedContentRequestAttribute or UmbracoVirtualNodeRouteHandler. Those in turn call this method + // to setup the rest of the pipeline but we don't want to run the finders since there's one assigned. + if (request.PublishedContent == null) + { + // find the document & template + FindPublishedContentAndTemplate(request); + } + + // handle wildcard domains + HandleWildcardDomains(request); + + // set the culture on the thread -- again, 'cos it might have changed due to a finder or wildcard domain + Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture = request.Culture; + + // trigger the Prepared event - at that point it is still possible to change about anything + // even though the request might be flagged for redirection - we'll redirect _after_ the event + // + // also, OnPrepared() will make the PublishedContentRequest readonly, so nothing can change + // + request.OnPrepared(); + + // we don't take care of anything so if the content has changed, it's up to the user + // to find out the appropriate template + + //complete the PCR and assign the remaining values + return ConfigureRequest(request); + } + + /// + /// Called by PrepareRequest once everything has been discovered, resolved and assigned to the PCR. This method + /// finalizes the PCR with the values assigned. + /// + /// + /// Returns false if the request was not successfully configured + /// + /// + /// This method logic has been put into it's own method in case developers have created a custom PCR or are assigning their own values + /// but need to finalize it themselves. + /// + public bool ConfigureRequest(PublishedContentRequest frequest) + { + if (frequest.HasPublishedContent == false) + { + return false; + } + + // set the culture on the thread -- again, 'cos it might have changed in the event handler + Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture = frequest.Culture; + + // if request has been flagged to redirect, or has no content to display, + // then return - whoever called us is in charge of actually redirecting + if (frequest.IsRedirect || frequest.HasPublishedContent == false) + { + return false; + } + + // we may be 404 _and_ have a content + + // can't go beyond that point without a PublishedContent to render + // it's ok not to have a template, in order to give MVC a chance to hijack routes + + // note - the page() ctor below will cause the "page" to get the value of all its + // "elements" ie of all the IPublishedContent property. If we use the object value, + // that will trigger macro execution - which can't happen because macro execution + // requires that _pcr.UmbracoPage is already initialized = catch-22. The "legacy" + // pipeline did _not_ evaluate the macros, ie it is using the data value, and we + // have to keep doing it because of that catch-22. + + // assign the legacy page back to the request + // handlers like default.aspx will want it and most macros currently need it + frequest.UmbracoPage = new page(frequest); + + // used by many legacy objects + frequest.UmbracoContext.HttpContext.Items["pageID"] = frequest.PublishedContent.Id; + frequest.UmbracoContext.HttpContext.Items["pageElements"] = frequest.UmbracoPage.Elements; + + return true; + } + + /// + /// Updates the request when there is no template to render the content. + /// + /// This is called from Mvc when there's a document to render but no template. + public void UpdateRequestOnMissingTemplate(PublishedContentRequest request) + { + // clear content + var content = request.PublishedContent; + request.PublishedContent = null; + + HandlePublishedContent(request); // will go 404 + FindTemplate(request); + + // if request has been flagged to redirect then return + // whoever called us is in charge of redirecting + if (request.IsRedirect) + return; + + if (request.HasPublishedContent == false) + { + // means the engine could not find a proper document to handle 404 + // restore the saved content so we know it exists + request.PublishedContent = content; + return; + } + + if (request.HasTemplate == false) + { + // means we may have a document, but we have no template + // at that point there isn't much we can do and there is no point returning + // to Mvc since Mvc can't do much either + return; + } + + // see note in PrepareRequest() + + // assign the legacy page back to the docrequest + // handlers like default.aspx will want it and most macros currently need it + request.UmbracoPage = new page(request); + + // these two are used by many legacy objects + request.UmbracoContext.HttpContext.Items["pageID"] = request.PublishedContent.Id; + request.UmbracoContext.HttpContext.Items["pageElements"] = request.UmbracoPage.Elements; + } + + #endregion + + #region Domain + + /// + /// Finds the site root (if any) matching the http request, and updates the PublishedContentRequest accordingly. + /// + /// A value indicating whether a domain was found. + internal bool FindDomain(PublishedContentRequest request) + { + const string tracePrefix = "FindDomain: "; + + // note - we are not handling schemes nor ports here. + + _logger.Debug("{0}Uri=\"{1}\"", () => tracePrefix, () => request.Uri); + + // try to find a domain matching the current request + var domainAndUri = DomainHelper.DomainForUri(request.UmbracoContext.Facade.DomainCache.GetAll(false), request.Uri); + + // handle domain - always has a contentId and a culture + if (domainAndUri != null) + { + // matching an existing domain + _logger.Debug("{0}Matches domain=\"{1}\", rootId={2}, culture=\"{3}\"", + () => tracePrefix, + () => domainAndUri.Name, + () => domainAndUri.ContentId, + () => domainAndUri.Culture); + + request.Domain = domainAndUri; + request.Culture = domainAndUri.Culture; + + // canonical? not implemented at the moment + // if (...) + // { + // _pcr.RedirectUrl = "..."; + // return true; + // } + } + else + { + // not matching any existing domain + _logger.Debug("{0}Matches no domain", () => tracePrefix); + + var defaultLanguage = _services.LocalizationService.GetAllLanguages().FirstOrDefault(); + request.Culture = defaultLanguage == null ? CultureInfo.CurrentUICulture : new CultureInfo(defaultLanguage.IsoCode); + } + + _logger.Debug("{0}Culture=\"{1}\"", () => tracePrefix, () => request.Culture.Name); + + return request.Domain != null; + } + + /// + /// Looks for wildcard domains in the path and updates Culture accordingly. + /// + internal void HandleWildcardDomains(PublishedContentRequest request) + { + const string tracePrefix = "HandleWildcardDomains: "; + + if (request.HasPublishedContent == false) + return; + + var nodePath = request.PublishedContent.Path; + _logger.Debug("{0}Path=\"{1}\"", () => tracePrefix, () => nodePath); + var rootNodeId = request.HasDomain ? request.Domain.ContentId : (int?)null; + var domain = DomainHelper.FindWildcardDomainInPath(request.UmbracoContext.Facade.DomainCache.GetAll(true), nodePath, rootNodeId); + + // always has a contentId and a culture + if (domain != null) + { + request.Culture = domain.Culture; + _logger.Debug("{0}Got domain on node {1}, set culture to \"{2}\".", () => tracePrefix, + () => domain.ContentId, () => request.Culture.Name); + } + else + { + _logger.Debug("{0}No match.", () => tracePrefix); + } + } + + #endregion + + #region Rendering engine + + /// + /// Finds the rendering engine to use to render a template specified by its alias. + /// + /// The alias of the template. + /// The rendering engine, or Unknown if the template was not found. + internal RenderingEngine FindTemplateRenderingEngine(string alias) + { + if (string.IsNullOrWhiteSpace(alias)) + return RenderingEngine.Unknown; + + alias = alias.Replace('\\', '/'); // forward slashes only + + // NOTE: we could start with what's the current default? + + // fixme - bad - we probably should be using the appropriate filesystems! + + if (FindTemplateRenderingEngineInDirectory(new DirectoryInfo(IOHelper.MapPath(SystemDirectories.MvcViews)), + alias, new[] { ".cshtml", ".vbhtml" })) + return RenderingEngine.Mvc; + + if (FindTemplateRenderingEngineInDirectory(new DirectoryInfo(IOHelper.MapPath(SystemDirectories.Masterpages)), + alias, new[] { ".master" })) + return RenderingEngine.WebForms; + + return RenderingEngine.Unknown; + } + + internal bool FindTemplateRenderingEngineInDirectory(DirectoryInfo directory, string alias, string[] extensions) + { + if (directory == null || directory.Exists == false) + return false; + + var pos = alias.IndexOf('/'); + if (pos > 0) + { + // recurse + var subdir = directory.GetDirectories(alias.Substring(0, pos)).FirstOrDefault(); + alias = alias.Substring(pos + 1); + return subdir != null && FindTemplateRenderingEngineInDirectory(subdir, alias, extensions); + } + + // look here + return directory.GetFiles().Any(f => extensions.Any(e => f.Name.InvariantEquals(alias + e))); + } + + #endregion + + #region Document and template + + /// + /// Gets a template. + /// + /// The template alias + /// The template. + public ITemplate GetTemplate(string alias) + { + return _services.FileService.GetTemplate(alias); + } + + /// + /// Finds the Umbraco document (if any) matching the request, and updates the PublishedContentRequest accordingly. + /// + /// A value indicating whether a document and template were found. + private void FindPublishedContentAndTemplate(PublishedContentRequest request) + { + const string tracePrefix = "FindPublishedContentAndTemplate: "; + _logger.Debug("{0}Path=\"{1}\"", () => tracePrefix, () => request.Uri.AbsolutePath); + + // run the document finders + FindPublishedContent(request); + + // if request has been flagged to redirect then return + // whoever called us is in charge of actually redirecting + // -- do not process anything any further -- + if (request.IsRedirect) + return; + + // not handling umbracoRedirect here but after LookupDocument2 + // so internal redirect, 404, etc has precedence over redirect + + // handle not-found, redirects, access... + HandlePublishedContent(request); + + // find a template + FindTemplate(request); + + // handle umbracoRedirect + FollowExternalRedirect(request); + } + + /// + /// Tries to find the document matching the request, by running the IPublishedContentFinder instances. + /// + /// There is no finder collection. + internal void FindPublishedContent(PublishedContentRequest request) + { + const string tracePrefix = "FindPublishedContent: "; + + // look for the document + // the first successful finder, if any, will set this.PublishedContent, and may also set this.Template + // some finders may implement caching + + using (_profilingLogger.DebugDuration( + $"{tracePrefix}Begin finders", + $"{tracePrefix}End finders, {(request.HasPublishedContent ? "a document was found" : "no document was found")}")) + { + //iterate but return on first one that finds it + var found = _contentFinders.Any(finder => + { + _logger.Debug("Finder " + finder.GetType().FullName); + return finder.TryFindContent(request); + }); + } + + // indicate that the published content (if any) we have at the moment is the + // one that was found by the standard finders before anything else took place. + request.SetIsInitialPublishedContent(); + } + + /// + /// Handles the published content (if any). + /// + /// + /// Handles "not found", internal redirects, access validation... + /// things that must be handled in one place because they can create loops + /// + private void HandlePublishedContent(PublishedContentRequest request) + { + const string tracePrefix = "HandlePublishedContent: "; + + // because these might loop, we have to have some sort of infinite loop detection + int i = 0, j = 0; + const int maxLoop = 8; + do + { + _logger.Debug("{0}{1}", () => tracePrefix, () => (i == 0 ? "Begin" : "Loop")); + + // handle not found + if (request.HasPublishedContent == false) + { + request.Is404 = true; + _logger.Debug("{0}No document, try last chance lookup", () => tracePrefix); + + // if it fails then give up, there isn't much more that we can do + if (_contentLastChanceFinder.TryFindContent(request) == false) + { + _logger.Debug("{0}Failed to find a document, give up", () => tracePrefix); + break; + } + + _logger.Debug("{0}Found a document", () => tracePrefix); + } + + // follow internal redirects as long as it's not running out of control ie infinite loop of some sort + j = 0; + while (FollowInternalRedirects(request) && j++ < maxLoop) + { } + if (j == maxLoop) // we're running out of control + break; + + // ensure access + if (request.HasPublishedContent) + EnsurePublishedContentAccess(request); + + // loop while we don't have page, ie the redirect or access + // got us to nowhere and now we need to run the notFoundLookup again + // as long as it's not running out of control ie infinite loop of some sort + + } while (request.HasPublishedContent == false && i++ < maxLoop); + + if (i == maxLoop || j == maxLoop) + { + _logger.Debug("{0}Looks like we're running into an infinite loop, abort", () => tracePrefix); + request.PublishedContent = null; + } + + _logger.Debug("{0}End", () => tracePrefix); + } + + /// + /// Follows internal redirections through the umbracoInternalRedirectId document property. + /// + /// A value indicating whether redirection took place and led to a new published document. + /// + /// Redirecting to a different site root and/or culture will not pick the new site root nor the new culture. + /// As per legacy, if the redirect does not work, we just ignore it. + /// + private bool FollowInternalRedirects(PublishedContentRequest request) + { + const string tracePrefix = "FollowInternalRedirects: "; + + if (request.PublishedContent == null) + throw new InvalidOperationException("There is no PublishedContent."); + + var redirect = false; + var internalRedirect = request.PublishedContent.Value(Constants.Conventions.Content.InternalRedirectId); + + if (string.IsNullOrWhiteSpace(internalRedirect)) + return false; + + _logger.Debug("{0}Found umbracoInternalRedirectId={1}", () => tracePrefix, () => internalRedirect); + + int internalRedirectId; + if (int.TryParse(internalRedirect, out internalRedirectId) == false) + internalRedirectId = -1; + + if (internalRedirectId <= 0) + { + // bad redirect - log and display the current page (legacy behavior) + //_pcr.Document = null; // no! that would be to force a 404 + _logger.Debug("{0}Failed to redirect to id={1}: invalid value", () => tracePrefix, () => internalRedirect); + } + else if (internalRedirectId == request.PublishedContent.Id) + { + // redirect to self + _logger.Debug("{0}Redirecting to self, ignore", () => tracePrefix); + } + else + { + // redirect to another page + var node = request.UmbracoContext.Facade.ContentCache.GetById(internalRedirectId); + + if (node != null) + { + request.SetInternalRedirectPublishedContent(node); // don't use .PublishedContent here + redirect = true; + _logger.Debug("{0}Redirecting to id={1}", () => tracePrefix, () => internalRedirectId); + } + else + { + _logger.Debug("{0}Failed to redirect to id={1}: no such published document", () => tracePrefix, () => internalRedirectId); + } + } + + return redirect; + } + + /// + /// Ensures that access to current node is permitted. + /// + /// Redirecting to a different site root and/or culture will not pick the new site root nor the new culture. + private void EnsurePublishedContentAccess(PublishedContentRequest request) + { + const string tracePrefix = "EnsurePublishedContentAccess: "; + + if (request.PublishedContent == null) + throw new InvalidOperationException("There is no PublishedContent."); + + var path = request.PublishedContent.Path; + + var publicAccessAttempt = _services.PublicAccessService.IsProtected(path); + + if (publicAccessAttempt) + { + _logger.Debug("{0}Page is protected, check for access", () => tracePrefix); + + var membershipHelper = new MembershipHelper(request.UmbracoContext); + + if (membershipHelper.IsLoggedIn() == false) + { + _logger.Debug("{0}Not logged in, redirect to login page", () => tracePrefix); + + var loginPageId = publicAccessAttempt.Result.LoginNodeId; + + if (loginPageId != request.PublishedContent.Id) + request.PublishedContent = request.UmbracoContext.Facade.ContentCache.GetById(loginPageId); + } + else if (_services.PublicAccessService.HasAccess(request.PublishedContent.Id, _services.ContentService, GetRolesForLogin(membershipHelper.CurrentUserName)) == false) + { + _logger.Debug("{0}Current member has not access, redirect to error page", () => tracePrefix); + var errorPageId = publicAccessAttempt.Result.NoAccessNodeId; + if (errorPageId != request.PublishedContent.Id) + request.PublishedContent = request.UmbracoContext.Facade.ContentCache.GetById(errorPageId); + } + else + { + _logger.Debug("{0}Current member has access", () => tracePrefix); + } + } + else + { + _logger.Debug("{0}Page is not protected", () => tracePrefix); + } + } + + /// + /// Finds a template for the current node, if any. + /// + private void FindTemplate(PublishedContentRequest request) + { + // NOTE: at the moment there is only 1 way to find a template, and then ppl must + // use the Prepared event to change the template if they wish. Should we also + // implement an ITemplateFinder logic? + + const string tracePrefix = "FindTemplate: "; + + if (request.PublishedContent == null) + { + request.TemplateModel = null; + return; + } + + // read the alternate template alias, from querystring, form, cookie or server vars, + // only if the published content is the initial once, else the alternate template + // does not apply + // + optionnally, apply the alternate template on internal redirects + var useAltTemplate = _webRoutingSection.DisableAlternativeTemplates == false + && (request.IsInitialPublishedContent + || (_webRoutingSection.InternalRedirectPreservesTemplate && request.IsInternalRedirectPublishedContent)); + var altTemplate = useAltTemplate + ? request.UmbracoContext.HttpContext.Request[Constants.Conventions.Url.AltTemplate] + : null; + + if (string.IsNullOrWhiteSpace(altTemplate)) + { + // we don't have an alternate template specified. use the current one if there's one already, + // which can happen if a content lookup also set the template (LookupByNiceUrlAndTemplate...), + // else lookup the template id on the document then lookup the template with that id. + + if (request.HasTemplate) + { + _logger.Debug("{0}Has a template already, and no alternate template.", () => tracePrefix); + return; + } + + // TODO: When we remove the need for a database for templates, then this id should be irrelavent, + // not sure how were going to do this nicely. + + var templateId = request.PublishedContent.TemplateId; + + if (templateId > 0) + { + _logger.Debug("{0}Look for template id={1}", () => tracePrefix, () => templateId); + var template = _services.FileService.GetTemplate(templateId); + if (template == null) + throw new InvalidOperationException("The template with Id " + templateId + " does not exist, the page cannot render"); + request.TemplateModel = template; + _logger.Debug("{0}Got template id={1} alias=\"{2}\"", () => tracePrefix, () => template.Id, () => template.Alias); + } + else + { + _logger.Debug("{0}No specified template.", () => tracePrefix); + } + } + else + { + // we have an alternate template specified. lookup the template with that alias + // this means the we override any template that a content lookup might have set + // so /path/to/page/template1?altTemplate=template2 will use template2 + + // ignore if the alias does not match - just trace + + if (request.HasTemplate) + _logger.Debug("{0}Has a template already, but also an alternate template.", () => tracePrefix); + _logger.Debug("{0}Look for alternate template alias=\"{1}\"", () => tracePrefix, () => altTemplate); + + var template = _services.FileService.GetTemplate(altTemplate); + if (template != null) + { + request.TemplateModel = template; + _logger.Debug("{0}Got template id={1} alias=\"{2}\"", () => tracePrefix, () => template.Id, () => template.Alias); + } + else + { + _logger.Debug("{0}The template with alias=\"{1}\" does not exist, ignoring.", () => tracePrefix, () => altTemplate); + } + } + + if (request.HasTemplate == false) + { + _logger.Debug("{0}No template was found.", () => tracePrefix); + + // initial idea was: if we're not already 404 and UmbracoSettings.HandleMissingTemplateAs404 is true + // then reset _pcr.Document to null to force a 404. + // + // but: because we want to let MVC hijack routes even though no template is defined, we decide that + // a missing template is OK but the request will then be forwarded to MVC, which will need to take + // care of everything. + // + // so, don't set _pcr.Document to null here + } + else + { + _logger.Debug("{0}Running with template id={1} alias=\"{2}\"", () => tracePrefix, () => request.TemplateModel.Id, () => request.TemplateModel.Alias); + } + } + + /// + /// Follows external redirection through umbracoRedirect document property. + /// + /// As per legacy, if the redirect does not work, we just ignore it. + private void FollowExternalRedirect(PublishedContentRequest request) + { + if (request.HasPublishedContent == false) return; + + var redirectId = request.PublishedContent.Value(Constants.Conventions.Content.Redirect, -1); + var redirectUrl = "#"; + if (redirectId > 0) + redirectUrl = request.UmbracoContext.UrlProvider.GetUrl(redirectId); + if (redirectUrl != "#") + request.SetRedirect(redirectUrl); + } + + #endregion + } +} diff --git a/src/Umbraco.Web/Routing/IContentFinder.cs b/src/Umbraco.Web/Routing/IContentFinder.cs index c29df43465..5f8e5f0575 100644 --- a/src/Umbraco.Web/Routing/IContentFinder.cs +++ b/src/Umbraco.Web/Routing/IContentFinder.cs @@ -8,9 +8,9 @@ namespace Umbraco.Web.Routing /// /// Tries to find and assign an Umbraco document to a PublishedContentRequest. /// - /// The PublishedContentRequest. + /// The PublishedContentRequest. /// A value indicating whether an Umbraco document was found and assigned. /// Optionally, can also assign the template or anything else on the document request, although that is not required. - bool TryFindContent(PublishedContentRequest contentRequest); + bool TryFindContent(PublishedContentRequest frequest); } } \ No newline at end of file diff --git a/src/Umbraco.Web/Routing/LegacyRequestInitializer.cs b/src/Umbraco.Web/Routing/LegacyRequestInitializer.cs index f7f455069b..d2a233a943 100644 --- a/src/Umbraco.Web/Routing/LegacyRequestInitializer.cs +++ b/src/Umbraco.Web/Routing/LegacyRequestInitializer.cs @@ -30,7 +30,7 @@ namespace Umbraco.Web.Routing // legacy - virtualUrl used by presentation/template.cs to handle
internal class PublishedContentNotFoundHandler : IHttpHandler { - string _message; + private readonly string _message; public PublishedContentNotFoundHandler() { } @@ -28,27 +28,24 @@ namespace Umbraco.Web.Routing response.Clear(); - var docreq = UmbracoContext.Current.PublishedContentRequest; + var frequest = UmbracoContext.Current.PublishedContentRequest; var reason = "Cannot render the page at url '{0}'."; - if (!docreq.HasPublishedContent) + if (frequest.HasPublishedContent == false) reason = "No umbraco document matches the url '{0}'."; - else if (!docreq.HasTemplate) + else if (frequest.HasTemplate == false) reason = "No template exists to render the document at url '{0}'."; response.Write("

Page not found

"); response.Write("

"); response.Write(string.Format(reason, HttpUtility.HtmlEncode(UmbracoContext.Current.OriginalRequestUrl.PathAndQuery))); response.Write("

"); - if (!string.IsNullOrWhiteSpace(_message)) + if (string.IsNullOrWhiteSpace(_message) == false) response.Write("

" + _message + "

"); response.Write("

This page can be replaced with a custom 404. Check the documentation for \"custom 404\".

"); response.Write("

This page is intentionally left ugly ;-)

"); response.Write(""); } - public bool IsReusable - { - get { return false; } - } + public bool IsReusable => false; } } diff --git a/src/Umbraco.Web/Routing/PublishedContentRequest.cs b/src/Umbraco.Web/Routing/PublishedContentRequest.cs index c9255fef67..93d3807efc 100644 --- a/src/Umbraco.Web/Routing/PublishedContentRequest.cs +++ b/src/Umbraco.Web/Routing/PublishedContentRequest.cs @@ -1,142 +1,54 @@ using System; -using System.Collections.Generic; -using System.ComponentModel; using System.Globalization; -using System.Web.Security; -using Umbraco.Core; -using Umbraco.Core.Configuration; -using Umbraco.Core.Configuration.UmbracoSettings; -using Umbraco.Core.Models; - using umbraco; -using umbraco.cms.businesslogic.web; +using Umbraco.Core.Configuration; +using Umbraco.Core.Models; using Umbraco.Core.Models.PublishedContent; using RenderingEngine = Umbraco.Core.RenderingEngine; namespace Umbraco.Web.Routing { + // todo - rename to FacadeRequest as soon as acceptable + /// /// Represents a request for one specified Umbraco IPublishedContent to be rendered /// by one specified template, using one specified Culture and RenderingEngine. /// public class PublishedContentRequest { - private bool _readonly; - private bool _readonlyUri; + private readonly FacadeRouter _facadeRouter; + + private bool _readonly; // after prepared + private bool _readonlyUri; // after preparing + private Uri _uri; // clean uri, no virtual dir, no trailing slash nor .aspx, nothing + private ITemplate _template; // template model if any else null + private bool _is404; + private DomainAndUri _domain; + private CultureInfo _culture; + private IPublishedContent _publishedContent; + private IPublishedContent _initialPublishedContent; // found by finders before 404, redirects, etc + private page _umbracoPage; // legacy /// - /// Triggers before the published content request is prepared. + /// Initializes a new instance of the class. /// - /// When the event triggers, no preparation has been done. It is still possible to - /// modify the request's Uri property, for example to restore its original, public-facing value - /// that might have been modified by an in-between equipement such as a load-balancer. - public static event EventHandler Preparing; - - /// - /// Triggers once the published content request has been prepared, but before it is processed. - /// - /// When the event triggers, preparation is done ie domain, culture, document, template, - /// rendering engine, etc. have been setup. It is then possible to change anything, before - /// the request is actually processed and rendered by Umbraco. - public static event EventHandler Prepared; - - // the engine that does all the processing - // because in order to keep things clean and separated, - // the content request is just a data holder - private readonly PublishedContentRequestEngine _engine; - - // the cleaned up uri - // the cleaned up Uri has no virtual directory, no trailing slash, no .aspx extension, etc. - private Uri _uri; - - /// - /// Initializes a new instance of the class with a specific Uri and routing context. - /// - /// The request Uri. - /// A routing context. - /// A callback method to return the roles for the provided login name when required - /// - public PublishedContentRequest(Uri uri, RoutingContext routingContext, IWebRoutingSection routingConfig, Func> getRolesForLogin) - { - if (uri == null) throw new ArgumentNullException("uri"); - if (routingContext == null) throw new ArgumentNullException("routingContext"); - - Uri = uri; - RoutingContext = routingContext; - GetRolesForLogin = getRolesForLogin; - - _engine = new PublishedContentRequestEngine( - routingConfig, - this); - - RenderingEngine = RenderingEngine.Unknown; - } - - [EditorBrowsable(EditorBrowsableState.Never)] - [Obsolete("Use the constructor specifying all dependencies instead")] - public PublishedContentRequest(Uri uri, RoutingContext routingContext) - : this(uri, routingContext, UmbracoConfig.For.UmbracoSettings().WebRouting, s => Roles.Provider.GetRolesForUser(s)) - { - } - - /// - /// Gets the engine associated to the request. - /// - internal PublishedContentRequestEngine Engine { get { return _engine; } } - - /// - /// Prepares the request. - /// - public void Prepare() - { - _engine.PrepareRequest(); - } - - /// - /// Called to configure the request - /// - /// - /// This public method is legacy, Prepare() has been made public now which should be used and ensures the domains are assigned and - /// if a public content item is already assigned Prepare() now ensures that the finders are not executed. - /// - [Obsolete("Use Prepare() instead which configures the request and wires up everything correctly")] - public void ConfigureRequest() + /// The facade router. + /// The Umbraco context. + /// The request Uri. + internal PublishedContentRequest(FacadeRouter facadeRouter, UmbracoContext umbracoContext, Uri uri = null) { - _engine.ConfigureRequest(); + if (facadeRouter == null) throw new ArgumentNullException(nameof(facadeRouter)); + if (umbracoContext == null) throw new ArgumentNullException(nameof(umbracoContext)); + UmbracoContext = umbracoContext; + _facadeRouter = facadeRouter; + Uri = uri ?? umbracoContext.CleanedUmbracoUrl; + RenderingEngine = RenderingEngine.Unknown; } - /// - /// Updates the request when there is no template to render the content. - /// - internal void UpdateOnMissingTemplate() - { - var __readonly = _readonly; - _readonly = false; - _engine.UpdateRequestOnMissingTemplate(); - _readonly = __readonly; - } - /// - /// Triggers the Preparing event. + /// Gets the UmbracoContext. /// - internal void OnPreparing() - { - Preparing?.Invoke(this, EventArgs.Empty); - _readonlyUri = true; - } - - /// - /// Triggers the Prepared event. - /// - internal void OnPrepared() - { - Prepared?.Invoke(this, EventArgs.Empty); - - if (HasPublishedContent == false) - Is404 = true; // safety - - _readonly = true; - } + public UmbracoContext UmbracoContext { get; } /// /// Gets or sets the cleaned up Uri used for routing. @@ -155,31 +67,70 @@ namespace Umbraco.Web.Routing } } + // utility for ensuring it is ok to set some properties private void EnsureWriteable() { if (_readonly) throw new InvalidOperationException("Cannot modify a PublishedContentRequest once it is read-only."); } - #region PublishedContent + /// + /// Prepares the request. + /// + public void Prepare() + { + _facadeRouter.PrepareRequest(this); + } - /// - /// The requested IPublishedContent, if any, else null. - /// - private IPublishedContent _publishedContent; + #region Events - /// - /// The initial requested IPublishedContent, if any, else null. - /// - /// The initial requested content is the content that was found by the finders, - /// before anything such as 404, redirect... took place. - private IPublishedContent _initialPublishedContent; + /// + /// Triggers before the published content request is prepared. + /// + /// When the event triggers, no preparation has been done. It is still possible to + /// modify the request's Uri property, for example to restore its original, public-facing value + /// that might have been modified by an in-between equipement such as a load-balancer. + public static event EventHandler Preparing; - /// - /// Gets or sets the requested content. - /// - /// Setting the requested content clears Template. - public IPublishedContent PublishedContent + /// + /// Triggers once the published content request has been prepared, but before it is processed. + /// + /// When the event triggers, preparation is done ie domain, culture, document, template, + /// rendering engine, etc. have been setup. It is then possible to change anything, before + /// the request is actually processed and rendered by Umbraco. + public static event EventHandler Prepared; + + /// + /// Triggers the Preparing event. + /// + internal void OnPreparing() + { + Preparing?.Invoke(this, EventArgs.Empty); + _readonlyUri = true; + } + + /// + /// Triggers the Prepared event. + /// + internal void OnPrepared() + { + Prepared?.Invoke(this, EventArgs.Empty); + + if (HasPublishedContent == false) + Is404 = true; // safety + + _readonly = true; + } + + #endregion + + #region PublishedContent + + /// + /// Gets or sets the requested content. + /// + /// Setting the requested content clears Template. + public IPublishedContent PublishedContent { get { return _publishedContent; } set @@ -199,7 +150,7 @@ namespace Umbraco.Web.Routing /// preserve or reset the template, if any. public void SetInternalRedirectPublishedContent(IPublishedContent content) { - if (content == null) throw new ArgumentNullException("content"); + if (content == null) throw new ArgumentNullException(nameof(content)); EnsureWriteable(); // unless a template has been set already by the finder, @@ -240,20 +191,14 @@ namespace Umbraco.Web.Routing /// /// The initial requested content is the content that was found by the finders, /// before anything such as 404, redirect... took place. - public IPublishedContent InitialPublishedContent { get { return _initialPublishedContent; } } + public IPublishedContent InitialPublishedContent => _initialPublishedContent; - /// + /// /// Gets value indicating whether the current published content is the initial one. /// - public bool IsInitialPublishedContent - { - get - { - return _initialPublishedContent != null && _initialPublishedContent == _publishedContent; - } - } + public bool IsInitialPublishedContent => _initialPublishedContent != null && _initialPublishedContent == _publishedContent; - /// + /// /// Indicates that the current PublishedContent is the initial one. /// public void SetIsInitialPublishedContent() @@ -276,20 +221,12 @@ namespace Umbraco.Web.Routing /// /// Gets a value indicating whether the content request has a content. /// - public bool HasPublishedContent - { - get { return PublishedContent != null; } - } + public bool HasPublishedContent => PublishedContent != null; - #endregion + #endregion #region Template - /// - /// The template model, if any, else null. - /// - private ITemplate _template; - /// /// Gets or sets the template model to use to display the requested content. /// @@ -304,24 +241,17 @@ namespace Umbraco.Web.Routing { _template = value; RenderingEngine = RenderingEngine.Unknown; // reset - if (_template != null) - RenderingEngine = _engine.FindTemplateRenderingEngine(_template.Alias); + RenderingEngine = _facadeRouter.FindTemplateRenderingEngine(_template.Alias); } } /// /// Gets the alias of the template to use to display the requested content. /// - public string TemplateAlias - { - get - { - return _template == null ? null : _template.Alias; - } - } + public string TemplateAlias => _template?.Alias; - /// + /// /// Tries to set the template to use to display the requested content. /// /// The alias of the template. @@ -343,7 +273,7 @@ namespace Umbraco.Web.Routing // NOTE - can we stil get it with whitespaces in it due to old legacy bugs? alias = alias.Replace(" ", ""); - var model = Current.Services.FileService.GetTemplate(alias); + var model = _facadeRouter.GetTemplate(alias); if (model == null) return false; @@ -375,30 +305,40 @@ namespace Umbraco.Web.Routing /// /// Gets a value indicating whether the content request has a template. /// - public bool HasTemplate + public bool HasTemplate => _template != null; + + internal void UpdateOnMissingTemplate() { - get { return _template != null; } + var __readonly = _readonly; + _readonly = false; + _facadeRouter.UpdateRequestOnMissingTemplate(this); + _readonly = __readonly; } #endregion #region Domain and Culture - //TODO: Should we publicize the setter now that we are using a non-legacy entity?? /// /// Gets or sets the content request's domain. /// /// Is a DomainAndUri object ie a standard Domain plus the fully qualified uri. For example, /// the Domain may contain "example.com" whereas the Uri will be fully qualified eg "http://example.com/". - public DomainAndUri Domain { get; internal set; } + public DomainAndUri Domain + { + get { return _domain; } + set + { + EnsureWriteable(); + _domain = value; + } + } /// /// Gets a value indicating whether the content request has a domain. /// public bool HasDomain => Domain != null; - private CultureInfo _culture; - /// /// Gets or sets the content request's culture. /// @@ -426,61 +366,30 @@ namespace Umbraco.Web.Routing #endregion - /// - /// Gets or sets the current RoutingContext. - /// - public RoutingContext RoutingContext { get; private set; } - - internal Func> GetRolesForLogin { get; private set; } - - /// - /// The "umbraco page" object. - /// - private page _umbracoPage; - - /// - /// Gets or sets the "umbraco page" object. - /// - /// - /// This value is only used for legacy/webforms code. - /// - internal page UmbracoPage - { - get - { - if (_umbracoPage == null) - throw new InvalidOperationException("The UmbracoPage object has not been initialized yet."); - - return _umbracoPage; - } - set { _umbracoPage = value; } - } - - #region Status - - /// - /// Gets or sets a value indicating whether the requested content could not be found. - /// - /// This is set in the PublishedContentRequestBuilder. - public bool Is404 { get; internal set; } + #region Status /// - /// Indicates that the requested content could not be found. + /// Gets or sets a value indicating whether the requested content could not be found. /// - /// This is for public access, in custom content finders or Prepared event handlers, - /// where we want to allow developers to indicate a request is 404 but not to cancel it. - public void SetIs404() - { - EnsureWriteable(); - Is404 = true; - } + /// This is set in the PublishedContentRequestBuilder and can also be used in + /// custom content finders or Prepared event handlers, where we want to allow developers + /// to indicate a request is 404 but not to cancel it. + public bool Is404 + { + get { return _is404; } + set + { + EnsureWriteable(); + _is404 = value; + } + } /// /// Gets a value indicating whether the content request triggers a redirect (permanent or not). /// - public bool IsRedirect { get { return string.IsNullOrWhiteSpace(RedirectUrl) == false; } } + public bool IsRedirect => string.IsNullOrWhiteSpace(RedirectUrl) == false; - /// + /// /// Gets or sets a value indicating whether the redirect is permanent. /// public bool IsRedirectPermanent { get; private set; } @@ -528,7 +437,7 @@ namespace Umbraco.Web.Routing EnsureWriteable(); if (status < 300 || status > 308) - throw new ArgumentOutOfRangeException("status", "Valid redirection status codes 300-308."); + throw new ArgumentOutOfRangeException(nameof(status), "Valid redirection status codes 300-308."); RedirectUrl = url; IsRedirectPermanent = (status == 301 || status == 308); @@ -569,5 +478,22 @@ namespace Umbraco.Web.Routing } #endregion + + #region Legacy + + // for legacy/webforms code - todo - get rid of it eventually + internal page UmbracoPage + { + get + { + if (_umbracoPage == null) + throw new InvalidOperationException("The UmbracoPage object has not been initialized yet."); + + return _umbracoPage; + } + set { _umbracoPage = value; } + } + + #endregion } } \ No newline at end of file diff --git a/src/Umbraco.Web/Routing/RoutingContext.cs b/src/Umbraco.Web/Routing/RoutingContext.cs deleted file mode 100644 index b999e2241a..0000000000 --- a/src/Umbraco.Web/Routing/RoutingContext.cs +++ /dev/null @@ -1,77 +0,0 @@ -using System; -using System.Collections.Generic; -using Umbraco.Web.PublishedCache; - -namespace Umbraco.Web.Routing -{ - - /// - /// Provides context for the routing of a request. - /// - public class RoutingContext - { - private readonly Lazy _urlProvider; - private readonly Lazy> _publishedContentFinders; - private readonly Lazy _publishedContentLastChanceFinder; - - /// - /// Initializes a new instance of the class. - /// - /// - /// The document lookups resolver. - /// - /// The nice urls provider. - internal RoutingContext( - UmbracoContext umbracoContext, - IEnumerable contentFinders, - IContentFinder contentLastChanceFinder, - UrlProvider urlProvider) - { - UmbracoContext = umbracoContext; - _publishedContentFinders = new Lazy>(() => contentFinders, false); - _publishedContentLastChanceFinder = new Lazy(() => contentLastChanceFinder, false); - _urlProvider = new Lazy(() => urlProvider, false); - } - - internal RoutingContext( - UmbracoContext umbracoContext, - Lazy> contentFinders, - Lazy contentLastChanceFinder, - Lazy urlProvider) - { - UmbracoContext = umbracoContext; - _publishedContentFinders = contentFinders; - _publishedContentLastChanceFinder = contentLastChanceFinder; - _urlProvider = urlProvider; - } - - /// - /// Gets the Umbraco context. - /// - public UmbracoContext UmbracoContext { get; private set; } - - /// - /// Gets the published content finders. - /// - internal IEnumerable PublishedContentFinders - { - get { return _publishedContentFinders.Value; } - } - - /// - /// Gets the published content last chance finder. - /// - internal IContentFinder PublishedContentLastChanceFinder - { - get { return _publishedContentLastChanceFinder.Value; } - } - - /// - /// Gets the urls provider. - /// - public UrlProvider UrlProvider - { - get { return _urlProvider.Value; } - } - } -} \ No newline at end of file diff --git a/src/Umbraco.Web/Routing/UrlProviderExtensions.cs b/src/Umbraco.Web/Routing/UrlProviderExtensions.cs index c6a792a6ae..226043420a 100644 --- a/src/Umbraco.Web/Routing/UrlProviderExtensions.cs +++ b/src/Umbraco.Web/Routing/UrlProviderExtensions.cs @@ -34,7 +34,7 @@ namespace Umbraco.Web.Routing return urls; } - var urlProvider = umbracoContext.RoutingContext.UrlProvider; + var urlProvider = umbracoContext.UrlProvider; var url = urlProvider.GetUrl(content.Id); if (url == "#") { diff --git a/src/Umbraco.Web/Templates/TemplateRenderer.cs b/src/Umbraco.Web/Templates/TemplateRenderer.cs index fe34036571..3608b041da 100644 --- a/src/Umbraco.Web/Templates/TemplateRenderer.cs +++ b/src/Umbraco.Web/Templates/TemplateRenderer.cs @@ -33,31 +33,37 @@ namespace Umbraco.Web.Templates public TemplateRenderer(UmbracoContext umbracoContext, int pageId, int? altTemplateId) { - if (umbracoContext == null) throw new ArgumentNullException("umbracoContext"); + if (umbracoContext == null) throw new ArgumentNullException(nameof(umbracoContext)); PageId = pageId; AltTemplate = altTemplateId; _umbracoContext = umbracoContext; } - /// - /// Gets/sets the page id for the template to render - /// - public int PageId { get; private set; } + // todo - inject! + private FacadeRouter FacadeRouter => Core.DI.Current.Container.GetInstance(); + + + /// + /// Gets/sets the page id for the template to render + /// + public int PageId { get; } /// /// Gets/sets the alt template to render if there is one /// - public int? AltTemplate { get; private set; } + public int? AltTemplate { get; } public void Render(StringWriter writer) { - if (writer == null) throw new ArgumentNullException("writer"); + if (writer == null) throw new ArgumentNullException(nameof(writer)); + // instanciate a request a process // important to use CleanedUmbracoUrl - lowercase path-only version of the current url, though this isn't going to matter // terribly much for this implementation since we are just creating a doc content request to modify it's properties manually. - var contentRequest = new PublishedContentRequest(_umbracoContext.CleanedUmbracoUrl, _umbracoContext.RoutingContext); + // fixme - previously that would create an aengine... + var contentRequest = FacadeRouter.CreateRequest(_umbracoContext); - var doc = contentRequest.RoutingContext.UmbracoContext.ContentCache.GetById(PageId); + var doc = contentRequest.UmbracoContext.ContentCache.GetById(PageId); if (doc == null) { @@ -88,9 +94,9 @@ namespace Umbraco.Web.Templates : _fileService.GetTemplate(AltTemplate.Value); //if there is not template then exit - if (!contentRequest.HasTemplate) + if (contentRequest.HasTemplate == false) { - if (!AltTemplate.HasValue) + if (AltTemplate.HasValue == false) { writer.Write("", doc.TemplateId); } @@ -138,7 +144,7 @@ namespace Umbraco.Web.Templates { Route = RouteTable.Routes["Umbraco_default"] }); - var routeHandler = new RenderRouteHandler(ControllerBuilder.Current.GetControllerFactory(), _umbracoContext); + var routeHandler = new RenderRouteHandler(_umbracoContext, ControllerBuilder.Current.GetControllerFactory()); var routeDef = routeHandler.GetUmbracoRouteDefinition(requestContext, contentRequest); var renderModel = new ContentModel(contentRequest.PublishedContent); //manually add the action/controller, this is required by mvc @@ -197,7 +203,7 @@ namespace Umbraco.Web.Templates //now, set the new ones for this page execution _umbracoContext.HttpContext.Items["pageID"] = contentRequest.PublishedContent.Id; _umbracoContext.HttpContext.Items["pageElements"] = contentRequest.UmbracoPage.Elements; - _umbracoContext.HttpContext.Items[Umbraco.Core.Constants.Conventions.Url.AltTemplate] = null; + _umbracoContext.HttpContext.Items[Core.Constants.Conventions.Url.AltTemplate] = null; _umbracoContext.PublishedContentRequest = contentRequest; } @@ -224,6 +230,5 @@ namespace Umbraco.Web.Templates _umbracoContext.HttpContext.Items["pageElements"] = _oldPageElements; _umbracoContext.HttpContext.Items[Umbraco.Core.Constants.Conventions.Url.AltTemplate] = _oldAltTemplate; } - } } \ No newline at end of file diff --git a/src/Umbraco.Web/Templates/TemplateUtilities.cs b/src/Umbraco.Web/Templates/TemplateUtilities.cs index aa4fb2716a..72f81b97fe 100644 --- a/src/Umbraco.Web/Templates/TemplateUtilities.cs +++ b/src/Umbraco.Web/Templates/TemplateUtilities.cs @@ -36,7 +36,7 @@ namespace Umbraco.Web.Templates //TODO: Pass in an Umbraco context!!!!!!!! Don't rely on the singleton so things are more testable, better yet, pass in urlprovider, routing context, separately //don't attempt to proceed without a context as we cannot lookup urls without one - if (UmbracoContext.Current == null || UmbracoContext.Current.RoutingContext == null) + if (UmbracoContext.Current == null) { return text; } diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index e7e6e9eaca..960ba8a69b 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -985,7 +985,7 @@ - + @@ -1110,7 +1110,6 @@ - Code diff --git a/src/Umbraco.Web/UmbracoContext.cs b/src/Umbraco.Web/UmbracoContext.cs index 3753ed4d5b..e9f94a6608 100644 --- a/src/Umbraco.Web/UmbracoContext.cs +++ b/src/Umbraco.Web/UmbracoContext.cs @@ -25,7 +25,6 @@ namespace Umbraco.Web /// This is a helper method which is called to ensure that the singleton context is created /// /// - /// /// /// /// @@ -84,7 +83,6 @@ namespace Umbraco.Web /// Creates a standalone UmbracoContext instance /// /// - /// /// /// /// @@ -105,40 +103,15 @@ namespace Umbraco.Web if (umbracoSettings == null) throw new ArgumentNullException(nameof(umbracoSettings)); if (urlProviders == null) throw new ArgumentNullException(nameof(urlProviders)); - // create the context - var umbracoContext = new UmbracoContext( - httpContext, - facadeService, - webSecurity); - - // create and assign the RoutingContext, - // note the circular dependency here - umbracoContext.RoutingContext = new RoutingContext( - umbracoContext, - - //TODO: Until the new cache is done we can't really expose these to override/mock - new Lazy>(() => Web.Current.ContentFinders), - new Lazy(() => Web.Current.LastChanceContentFinder), - - // create the nice urls provider - // there's one per request because there are some behavior parameters that can be changed - new Lazy( - () => new UrlProvider( - umbracoContext, - umbracoSettings.WebRouting, - urlProviders), - false)); - - return umbracoContext; + return new UmbracoContext(httpContext, facadeService, webSecurity, umbracoSettings, urlProviders); } - /// An HttpContext. - /// A facade service. - /// A web security. private UmbracoContext( HttpContextBase httpContext, IFacadeService facadeService, - WebSecurity webSecurity) + WebSecurity webSecurity, + IUmbracoSettingsSection umbracoSettings, + IEnumerable urlProviders) { // ensure that this instance is disposed when the request terminates, though we *also* ensure // this happens in the Umbraco module since the UmbracoCOntext is added to the HttpContext items. @@ -170,6 +143,8 @@ namespace Umbraco.Web // OriginalRequestUrl = GetRequestFromContext()?.Url ?? new Uri("http://localhost"); CleanedUmbracoUrl = UriUtility.UriToUmbraco(OriginalRequestUrl); + + UrlProvider = new UrlProvider(this, umbracoSettings.WebRouting, urlProviders); } #endregion @@ -232,25 +207,9 @@ namespace Umbraco.Web public bool IsFrontEndUmbracoRequest => PublishedContentRequest != null; /// - /// A shortcut to the UmbracoContext's RoutingContext's NiceUrlProvider + /// Gets the url provider. /// - /// - /// If the RoutingContext is null, this will throw an exception. - /// - public UrlProvider UrlProvider - { - get - { - if (RoutingContext == null) - throw new InvalidOperationException("Cannot access the UrlProvider when the UmbracoContext's RoutingContext is null"); - return RoutingContext.UrlProvider; - } - } - - /// - /// Gets/sets the RoutingContext object - /// - public RoutingContext RoutingContext { get; internal set; } + public UrlProvider UrlProvider { get; } /// /// Gets/sets the PublishedContentRequest object diff --git a/src/Umbraco.Web/UmbracoHelper.cs b/src/Umbraco.Web/UmbracoHelper.cs index 93d2b3ab29..295e523cf0 100644 --- a/src/Umbraco.Web/UmbracoHelper.cs +++ b/src/Umbraco.Web/UmbracoHelper.cs @@ -117,7 +117,6 @@ namespace Umbraco.Web if (umbracoContext == null) throw new ArgumentNullException(nameof(umbracoContext)); if (services == null) throw new ArgumentNullException(nameof(services)); if (appCache == null) throw new ArgumentNullException(nameof(appCache)); - if (umbracoContext.RoutingContext == null) throw new NullReferenceException("The RoutingContext on the UmbracoContext cannot be null."); _umbracoContext = umbracoContext; if (_umbracoContext.IsFrontEndUmbracoRequest) diff --git a/src/Umbraco.Web/UmbracoModule.cs b/src/Umbraco.Web/UmbracoModule.cs index 94b9768f70..7d503b9ebc 100644 --- a/src/Umbraco.Web/UmbracoModule.cs +++ b/src/Umbraco.Web/UmbracoModule.cs @@ -14,7 +14,6 @@ using Umbraco.Web.Security; using Umbraco.Core.Collections; using Umbraco.Core.Exceptions; using Umbraco.Core.Services; -using Umbraco.Core.Sync; using Umbraco.Web.PublishedCache; using GlobalSettings = Umbraco.Core.Configuration.GlobalSettings; @@ -49,6 +48,9 @@ namespace Umbraco.Web [Inject] public ILogger Logger { get; set; } + [Inject] + internal FacadeRouter FacadeRouter { get; set; } + #endregion public UmbracoModule() @@ -112,8 +114,6 @@ namespace Umbraco.Web if (UmbracoContext.Current == null) throw new InvalidOperationException("The UmbracoContext.Current is null, ProcessRequest cannot proceed unless there is a current UmbracoContext"); - if (UmbracoContext.Current.RoutingContext == null) - throw new InvalidOperationException("The UmbracoContext.RoutingContext has not been assigned, ProcessRequest cannot proceed unless there is a RoutingContext assigned to the UmbracoContext"); var umbracoContext = UmbracoContext.Current; @@ -142,19 +142,19 @@ namespace Umbraco.Web // instanciate, prepare and process the published content request // important to use CleanedUmbracoUrl - lowercase path-only version of the current url - var pcr = new PublishedContentRequest(umbracoContext.CleanedUmbracoUrl, umbracoContext.RoutingContext); - umbracoContext.PublishedContentRequest = pcr; - pcr.Prepare(); + var request = FacadeRouter.CreateRequest(umbracoContext); + umbracoContext.PublishedContentRequest = request; + FacadeRouter.PrepareRequest(request); // HandleHttpResponseStatus returns a value indicating that the request should // not be processed any further, eg because it has been redirect. then, exit. - if (HandleHttpResponseStatus(httpContext, pcr, Logger)) + if (HandleHttpResponseStatus(httpContext, request, Logger)) return; - if (pcr.HasPublishedContent == false) + if (request.HasPublishedContent == false) httpContext.RemapHandler(new PublishedContentNotFoundHandler()); else - RewriteToUmbracoHandler(httpContext, pcr); + RewriteToUmbracoHandler(httpContext, request); } #endregion diff --git a/src/Umbraco.Web/WebRuntimeComponent.cs b/src/Umbraco.Web/WebRuntimeComponent.cs index 42488a9466..f71fcc0cdd 100644 --- a/src/Umbraco.Web/WebRuntimeComponent.cs +++ b/src/Umbraco.Web/WebRuntimeComponent.cs @@ -172,6 +172,7 @@ namespace Umbraco.Web internal void Initialize( IRuntimeState runtime, + IUmbracoContextAccessor umbracoContextAccessor, SurfaceControllerTypeCollection surfaceControllerTypes, UmbracoApiControllerTypeCollection apiControllerTypes) { @@ -209,7 +210,7 @@ namespace Umbraco.Web ConfigureGlobalFilters(); // set routes - CreateRoutes(surfaceControllerTypes, apiControllerTypes); + CreateRoutes(umbracoContextAccessor, surfaceControllerTypes, apiControllerTypes); // get an http context // fixme - although HttpContext.Current is NOT null during Application_Start @@ -269,6 +270,7 @@ namespace Umbraco.Web // internal for tests internal static void CreateRoutes( + IUmbracoContextAccessor umbracoContextAccessor, SurfaceControllerTypeCollection surfaceControllerTypes, UmbracoApiControllerTypeCollection apiControllerTypes) { @@ -280,7 +282,7 @@ namespace Umbraco.Web umbracoPath + "/RenderMvc/{action}/{id}", new { controller = "RenderMvc", action = "Index", id = UrlParameter.Optional } ); - defaultRoute.RouteHandler = new RenderRouteHandler(ControllerBuilder.Current.GetControllerFactory()); + defaultRoute.RouteHandler = new RenderRouteHandler(umbracoContextAccessor, ControllerBuilder.Current.GetControllerFactory()); // register install routes RouteTable.Routes.RegisterArea(); diff --git a/src/Umbraco.Web/umbraco.presentation/default.aspx.cs b/src/Umbraco.Web/umbraco.presentation/default.aspx.cs index c2aa38c663..646ace2ec9 100644 --- a/src/Umbraco.Web/umbraco.presentation/default.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/default.aspx.cs @@ -38,18 +38,13 @@ namespace umbraco } private page _upage; - private PublishedContentRequest _docRequest; - bool _validateRequest = true; + private PublishedContentRequest _frequest; /// /// To turn off request validation set this to false before the PageLoad event. This equivalent to the validateRequest page directive /// and has nothing to do with "normal" validation controls. Default value is true. /// - public bool ValidateRequest - { - get { return _validateRequest; } - set { _validateRequest = value; } - } + public bool ValidateRequest { get; set; } = true; protected override void OnPreInit(EventArgs e) { @@ -61,8 +56,8 @@ namespace umbraco Page.Trace.IsEnabled &= GlobalSettings.DebugMode && string.IsNullOrWhiteSpace(Request["umbDebugShowTrace"]) == false; // get the document request and the page - _docRequest = UmbracoContext.Current.PublishedContentRequest; - _upage = _docRequest.UmbracoPage; + _frequest = UmbracoContext.Current.PublishedContentRequest; + _upage = _frequest.UmbracoPage; //we need to check this for backwards compatibility in case people still arent' using master pages if (UmbracoConfig.For.UmbracoSettings().Templates.UseAspNetMasterPages) diff --git a/src/Umbraco.Web/umbraco.presentation/page.cs b/src/Umbraco.Web/umbraco.presentation/page.cs index aa6a0b3491..654004b537 100644 --- a/src/Umbraco.Web/umbraco.presentation/page.cs +++ b/src/Umbraco.Web/umbraco.presentation/page.cs @@ -93,31 +93,31 @@ namespace umbraco /// /// Initializes a new instance of the class for a published document request. /// - /// The pointing to the document. + /// The pointing to the document. /// /// The difference between creating the page with PublishedContentRequest vs an IPublishedContent item is /// that the PublishedContentRequest takes into account how a template is assigned during the routing process whereas /// with an IPublishedContent item, the template id is asssigned purely based on the default. /// - internal page(PublishedContentRequest docreq) + internal page(PublishedContentRequest frequest) { - if (!docreq.HasPublishedContent) - throw new ArgumentException("Document request has no node.", "docreq"); + if (!frequest.HasPublishedContent) + throw new ArgumentException("Document request has no node.", "frequest"); - populatePageData(docreq.PublishedContent.Id, - docreq.PublishedContent.Name, docreq.PublishedContent.DocumentTypeId, docreq.PublishedContent.DocumentTypeAlias, - docreq.PublishedContent.WriterName, docreq.PublishedContent.CreatorName, docreq.PublishedContent.CreateDate, docreq.PublishedContent.UpdateDate, - docreq.PublishedContent.Path, docreq.PublishedContent.Version, docreq.PublishedContent.Parent == null ? -1 : docreq.PublishedContent.Parent.Id); + populatePageData(frequest.PublishedContent.Id, + frequest.PublishedContent.Name, frequest.PublishedContent.DocumentTypeId, frequest.PublishedContent.DocumentTypeAlias, + frequest.PublishedContent.WriterName, frequest.PublishedContent.CreatorName, frequest.PublishedContent.CreateDate, frequest.PublishedContent.UpdateDate, + frequest.PublishedContent.Path, frequest.PublishedContent.Version, frequest.PublishedContent.Parent == null ? -1 : frequest.PublishedContent.Parent.Id); - if (docreq.HasTemplate) + if (frequest.HasTemplate) { - this._template = docreq.TemplateModel.Id; + this._template = frequest.TemplateModel.Id; _elements["template"] = _template.ToString(); } - PopulateElementData(docreq.PublishedContent); + PopulateElementData(frequest.PublishedContent); }