From 5e9d7915238d35e63b1f8d7460e21fe874cf17c1 Mon Sep 17 00:00:00 2001 From: Shannon Deminick Date: Fri, 7 Sep 2012 08:28:18 +0700 Subject: [PATCH] Moved the DocumentNotFoundHandler to diff namespace, created new NoTemplateHandler and updated the engine to route to it when no template is selected and when there are no hijacked routes. --- src/Umbraco.Web/Mvc/RenderRouteHandler.cs | 60 ++++++++++++------- src/Umbraco.Web/Mvc/RouteDefinition.cs | 7 ++- .../DocumentNotFoundHandler.cs} | 11 +--- src/Umbraco.Web/Routing/NoTemplateHandler.cs | 31 ++++++++++ src/Umbraco.Web/Umbraco.Web.csproj | 3 +- src/Umbraco.Web/UmbracoModule.cs | 2 +- .../umbraco.presentation/requestHandler.cs | 1 + 7 files changed, 81 insertions(+), 34 deletions(-) rename src/Umbraco.Web/{DocumentNotFoundHttpHandler.cs => Routing/DocumentNotFoundHandler.cs} (80%) create mode 100644 src/Umbraco.Web/Routing/NoTemplateHandler.cs diff --git a/src/Umbraco.Web/Mvc/RenderRouteHandler.cs b/src/Umbraco.Web/Mvc/RenderRouteHandler.cs index e6e22fe57a..a637d236d1 100644 --- a/src/Umbraco.Web/Mvc/RenderRouteHandler.cs +++ b/src/Umbraco.Web/Mvc/RenderRouteHandler.cs @@ -63,48 +63,55 @@ namespace Umbraco.Web.Mvc /// internal virtual RouteDefinition GetUmbracoRouteDefinition(RequestContext requestContext, DocumentRequest documentRequest) { + var defaultControllerName = ControllerExtensions.GetControllerName(); //creates the default route definition which maps to the 'UmbracoController' controller var def = new RouteDefinition { - ControllerName = ControllerExtensions.GetControllerName(), + ControllerName = defaultControllerName, Controller = new RenderMvcController(), DocumentRequest = documentRequest, - ActionName = ((Route)requestContext.RouteData.Route).Defaults["action"].ToString() + ActionName = ((Route)requestContext.RouteData.Route).Defaults["action"].ToString(), + HasHijackedRoute = false }; - //check that a template is defined) - if (documentRequest.HasTemplate) + //check if there's a custom controller assigned, base on the document type alias. + var controller = _controllerFactory.CreateController(requestContext, documentRequest.Document.DocumentTypeAlias); + + + //check if that controller exists + if (controller != null) { - //check if there's a custom controller assigned, base on the document type alias. - var controller = _controllerFactory.CreateController(requestContext, documentRequest.Document.DocumentTypeAlias); - - - //check if that controller exists - if (controller != null) + //ensure the controller is of type 'RenderMvcController' + if (controller is RenderMvcController) { - - //ensure the controller is of type 'RenderMvcController' - if (controller is RenderMvcController) + //set the controller and name to the custom one + def.Controller = (ControllerBase)controller; + def.ControllerName = ControllerExtensions.GetControllerName(controller.GetType()); + if (def.ControllerName != defaultControllerName) { - //set the controller and name to the custom one - def.Controller = (ControllerBase)controller; - def.ControllerName = ControllerExtensions.GetControllerName(controller.GetType()); - } - else - { - LogHelper.Warn("The current Document Type {0} matches a locally declared controller of type {1}. Custom Controllers for Umbraco routing must inherit from '{2}'.", documentRequest.Document.DocumentTypeAlias, controller.GetType().FullName, typeof(RenderMvcController).FullName); - //exit as we cannnot route to the custom controller, just route to the standard one. - return def; + def.HasHijackedRoute = true; } + } + else + { + LogHelper.Warn("The current Document Type {0} matches a locally declared controller of type {1}. Custom Controllers for Umbraco routing must inherit from '{2}'.", documentRequest.Document.DocumentTypeAlias, controller.GetType().FullName, typeof(RenderMvcController).FullName); + //exit as we cannnot route to the custom controller, just route to the standard one. + return def; + } + //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 (documentRequest.HasTemplate) + { //check if the custom controller has an action with the same name as the template name (we convert ToUmbracoAlias since the template name might have invalid chars). //NOTE: This also means that all custom actions MUST be PascalCase.. but that should be standard. var templateName = documentRequest.Template.Alias.Split('.')[0].ToUmbracoAlias(StringAliasCaseType.PascalCase); def.ActionName = templateName; - } + } + return def; } @@ -118,6 +125,13 @@ namespace Umbraco.Web.Mvc { var routeDef = GetUmbracoRouteDefinition(requestContext, documentRequest); + //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 (!documentRequest.HasTemplate && !routeDef.HasHijackedRoute) + { + return new NoTemplateHandler(); + } + //no post values, just route to the controller/action requried (local) requestContext.RouteData.Values["controller"] = routeDef.ControllerName; diff --git a/src/Umbraco.Web/Mvc/RouteDefinition.cs b/src/Umbraco.Web/Mvc/RouteDefinition.cs index 41ae6b99da..a157c034e6 100644 --- a/src/Umbraco.Web/Mvc/RouteDefinition.cs +++ b/src/Umbraco.Web/Mvc/RouteDefinition.cs @@ -5,7 +5,7 @@ namespace Umbraco.Web.Mvc /// /// Represents the data required to route to a specific controller/action during an Umbraco request /// - public class RouteDefinition + internal class RouteDefinition { public string ControllerName { get; set; } public string ActionName { get; set; } @@ -19,5 +19,10 @@ namespace Umbraco.Web.Mvc /// The current RenderModel found for the request /// public object DocumentRequest { get; set; } + + /// + /// Gets/sets whether the current request has a hijacked route/user controller routed for it + /// + public bool HasHijackedRoute { get; set; } } } \ No newline at end of file diff --git a/src/Umbraco.Web/DocumentNotFoundHttpHandler.cs b/src/Umbraco.Web/Routing/DocumentNotFoundHandler.cs similarity index 80% rename from src/Umbraco.Web/DocumentNotFoundHttpHandler.cs rename to src/Umbraco.Web/Routing/DocumentNotFoundHandler.cs index 26c8f97bc1..e578e8d5a7 100644 --- a/src/Umbraco.Web/DocumentNotFoundHttpHandler.cs +++ b/src/Umbraco.Web/Routing/DocumentNotFoundHandler.cs @@ -1,16 +1,11 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Web; +using System.Web; -namespace Umbraco.Web +namespace Umbraco.Web.Routing { - /// /// Gets executed when no document can be found in Umbraco /// - public class DocumentNotFoundHttpHandler : IHttpHandler + internal class DocumentNotFoundHandler : IHttpHandler { public void ProcessRequest(HttpContext context) { diff --git a/src/Umbraco.Web/Routing/NoTemplateHandler.cs b/src/Umbraco.Web/Routing/NoTemplateHandler.cs new file mode 100644 index 0000000000..43ba2cd6c8 --- /dev/null +++ b/src/Umbraco.Web/Routing/NoTemplateHandler.cs @@ -0,0 +1,31 @@ +using System.Web; + +namespace Umbraco.Web.Routing +{ + /// + /// Gets executed when there is no template assigned to a request and there is no hijacked MVC route + /// + internal class NoTemplateHandler : IHttpHandler + { + public void ProcessRequest(HttpContext context) + { + WriteOutput(context); + } + + internal void WriteOutput(HttpContext context) + { + context.Response.Clear(); + context.Response.Write(""); + context.Response.End(); + } + + public bool IsReusable + { + get + { + //yes this is reusable since it always returns the same thing + return true; + } + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index dbc9e6f9b5..6bf708e859 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -260,6 +260,7 @@ + ASPXCodeBehind @@ -270,7 +271,7 @@ - + diff --git a/src/Umbraco.Web/UmbracoModule.cs b/src/Umbraco.Web/UmbracoModule.cs index 98dd114f3c..e7c0951723 100644 --- a/src/Umbraco.Web/UmbracoModule.cs +++ b/src/Umbraco.Web/UmbracoModule.cs @@ -115,7 +115,7 @@ namespace Umbraco.Web //if no doc is found, send to our not found handler if (docreq.Is404) { - httpContext.RemapHandler(new DocumentNotFoundHttpHandler()); + httpContext.RemapHandler(new DocumentNotFoundHandler()); } else { diff --git a/src/Umbraco.Web/umbraco.presentation/requestHandler.cs b/src/Umbraco.Web/umbraco.presentation/requestHandler.cs index af13b54297..e069f1ca70 100644 --- a/src/Umbraco.Web/umbraco.presentation/requestHandler.cs +++ b/src/Umbraco.Web/umbraco.presentation/requestHandler.cs @@ -16,6 +16,7 @@ namespace umbraco { /// /// Summary description for requestHandler. /// + [Obsolete("This class is no longer used and will be removed in future versions")] public class requestHandler { #region public properties