/// <summary> /// Returns a RouteDefinition object based on the current renderModel /// </summary> /// <param name="requestContext"></param> /// <param name="publishedContentRequest"></param> /// <returns></returns> internal virtual RouteDefinition GetUmbracoRouteDefinition(RequestContext requestContext, PublishedContentRequest publishedContentRequest) { var defaultControllerName = ControllerExtensions.GetControllerName <RenderMvcController>(); //creates the default route definition which maps to the 'UmbracoController' controller var def = new RouteDefinition { ControllerName = defaultControllerName, Controller = new RenderMvcController(), PublishedContentRequest = publishedContentRequest, ActionName = ((Route)requestContext.RouteData.Route).Defaults["action"].ToString(), HasHijackedRoute = false }; //check if there's a custom controller assigned, base on the document type alias. var controller = _controllerFactory.CreateController(requestContext, publishedContentRequest.PublishedContent.DocumentTypeAlias); //check if that controller exists if (controller != null) { //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) { def.HasHijackedRoute = true; } } else { LogHelper.Warn <RenderRouteHandler>("The current Document Type {0} matches a locally declared controller of type {1}. Custom Controllers for Umbraco routing must inherit from '{2}'.", publishedContentRequest.PublishedContent.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 (publishedContentRequest.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 = publishedContentRequest.Template.Alias.Split('.')[0].ToUmbracoAlias(StringAliasCaseType.PascalCase); def.ActionName = templateName; } } return(def); }
public IHttpHandler GetHttpHandler(RequestContext requestContext) { var umbracoContext = GetUmbracoContext(requestContext); 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 }; //allows inheritors to change the pcr PreparePublishedContentRequest(umbracoContext.PublishedContentRequest); //create the render model var renderModel = new RenderModel(umbracoContext.PublishedContentRequest.PublishedContent, umbracoContext.PublishedContentRequest.Culture); //assigns the required tokens to the request requestContext.RouteData.DataTokens.Add(Core.Constants.Web.UmbracoDataToken, renderModel); requestContext.RouteData.DataTokens.Add(Core.Constants.Web.PublishedDocumentRequestDataToken, umbracoContext.PublishedContentRequest); requestContext.RouteData.DataTokens.Add(Core.Constants.Web.UmbracoContextDataToken, umbracoContext); //this is used just for a flag that this is an umbraco custom route requestContext.RouteData.DataTokens.Add(Core.Constants.Web.CustomRouteDataToken, true); //Here we need to detect if a SurfaceController has posted var formInfo = RenderRouteHandler.GetFormInfo(requestContext); if (formInfo != null) { var def = new RouteDefinition { ActionName = requestContext.RouteData.GetRequiredString("action"), ControllerName = requestContext.RouteData.GetRequiredString("controller"), PublishedContentRequest = umbracoContext.PublishedContentRequest }; //set the special data token to the current route definition requestContext.RouteData.DataTokens[Umbraco.Core.Constants.Web.UmbracoRouteDefinitionDataToken] = def; return(RenderRouteHandler.HandlePostedValues(requestContext, formInfo)); } return(new MvcHandler(requestContext)); }
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) { PublishedContent = found }; //allows inheritors to change the pcr PreparePublishedContentRequest(umbracoContext.PublishedContentRequest); //create the render model var renderModel = new RenderModel(umbracoContext.PublishedContentRequest.PublishedContent, umbracoContext.PublishedContentRequest.Culture); //assigns the required tokens to the request requestContext.RouteData.DataTokens.Add("umbraco", renderModel); requestContext.RouteData.DataTokens.Add("umbraco-doc-request", umbracoContext.PublishedContentRequest); requestContext.RouteData.DataTokens.Add("umbraco-context", umbracoContext); //this is used just for a flag that this is an umbraco custom route requestContext.RouteData.DataTokens.Add("umbraco-custom-route", true); //Here we need to detect if a SurfaceController has posted var formInfo = RenderRouteHandler.GetFormInfo(requestContext); if (formInfo != null) { var def = new RouteDefinition { ActionName = requestContext.RouteData.GetRequiredString("action"), ControllerName = requestContext.RouteData.GetRequiredString("controller"), PublishedContentRequest = umbracoContext.PublishedContentRequest }; //set the special data token to the current route definition requestContext.RouteData.DataTokens["umbraco-route-def"] = def; return(RenderRouteHandler.HandlePostedValues(requestContext, formInfo)); } return(new MvcHandler(requestContext)); }
/// <summary> /// Returns a RouteDefinition object based on the current content request /// </summary> /// <param name="requestContext"></param> /// <param name="request"></param> /// <returns></returns> internal virtual RouteDefinition GetUmbracoRouteDefinition(RequestContext requestContext, PublishedRequest request) { 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); //creates the default route definition which maps to the 'UmbracoController' controller var def = new RouteDefinition { ControllerName = defaultControllerName, ControllerType = defaultControllerType, PublishedRequest = 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 (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 = 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, request.PublishedContent.ContentType.Alias); //check if that controller exists if (controllerType != null) { //ensure the controller is of type IRenderMvcController and ControllerBase if (TypeHelper.IsTypeAssignableFrom <IRenderController>(controllerType) && TypeHelper.IsTypeAssignableFrom <ControllerBase>(controllerType)) { //set the controller and name to the custom one def.ControllerType = controllerType; def.ControllerName = ControllerExtensions.GetControllerName(controllerType); if (def.ControllerName != defaultControllerName) { def.HasHijackedRoute = true; } } else { Current.Logger.Warn <RenderRouteHandler>("The current Document Type {ContentTypeAlias} matches a locally declared controller of type {ControllerName}. Custom Controllers for Umbraco routing must implement '{UmbracoRenderController}' and inherit from '{UmbracoControllerBase}'.", request.PublishedContent.ContentType.Alias, controllerType.FullName, typeof(IRenderController).FullName, typeof(ControllerBase).FullName); //we cannot route to this custom controller since it is not of the correct type so we'll continue with the defaults // that have already been set above. } } //store the route definition requestContext.RouteData.DataTokens[Core.Constants.Web.UmbracoRouteDefinitionDataToken] = def; return(def); }
/// <summary> /// Handles a posted form to an Umbraco Url and ensures the correct controller is routed to and that /// the right DataTokens are set. /// </summary> /// <param name="requestContext"></param> /// <param name="postedInfo"></param> /// <param name="routeDefinition">The original route definition that would normally be used to route if it were not a POST</param> private IHttpHandler HandlePostedValues(RequestContext requestContext, PostedDataProxyInfo postedInfo, RouteDefinition routeDefinition) { var standardArea = Umbraco.Core.Configuration.GlobalSettings.UmbracoMvcArea; //set the standard route values/tokens requestContext.RouteData.Values["controller"] = postedInfo.ControllerName; requestContext.RouteData.Values["action"] = postedInfo.ActionName; requestContext.RouteData.DataTokens["area"] = postedInfo.Area; IHttpHandler handler = new MvcHandler(requestContext); //ensure the controllerType is set if found, meaning it is a plugin, not locally declared if (postedInfo.Area != standardArea) { //requestContext.RouteData.Values["controllerType"] = postedInfo.ControllerType; //find the other data tokens for this route and merge... things like Namespace will be included here using (RouteTable.Routes.GetReadLock()) { var surfaceRoute = RouteTable.Routes.OfType <Route>() .SingleOrDefault(x => x.Defaults != null && x.Defaults.ContainsKey("controller") && x.Defaults["controller"].ToString() == postedInfo.ControllerName && x.DataTokens.ContainsKey("area") && x.DataTokens["area"].ToString() == postedInfo.Area); if (surfaceRoute == null) { throw new InvalidOperationException("Could not find a Surface controller route in the RouteTable for controller name " + postedInfo.ControllerName + " and within the area of " + postedInfo.Area); } //set the 'Namespaces' token so the controller factory knows where to look to construct it if (surfaceRoute.DataTokens.ContainsKey("Namespaces")) { requestContext.RouteData.DataTokens["Namespaces"] = surfaceRoute.DataTokens["Namespaces"]; } handler = surfaceRoute.RouteHandler.GetHttpHandler(requestContext); } } //store the original URL this came in on requestContext.RouteData.DataTokens["umbraco-item-url"] = requestContext.HttpContext.Request.Url.AbsolutePath; //store the original route definition requestContext.RouteData.DataTokens["umbraco-route-def"] = routeDefinition; return(handler); }
/// <summary> /// Creates a controller using the controller factory /// </summary> private static ControllerBase CreateController(ControllerContext context, IControllerFactory factory, RouteDefinition routeDef) { var controller = factory.CreateController(context.RequestContext, routeDef.ControllerName) as ControllerBase; if (controller == null) { throw new InvalidOperationException("Could not create controller with name " + routeDef.ControllerName + "."); } return(controller); }
/// <summary> /// Creates a controller using the controller factory /// </summary> private static ControllerBase CreateController(ControllerContext context, IControllerFactory factory, RouteDefinition routeDef) { var controller = factory.CreateController(context.RequestContext, routeDef.ControllerName) as ControllerBase; if (controller == null) throw new InvalidOperationException("Could not create controller with name " + routeDef.ControllerName + "."); return controller; }
/// <summary> /// Returns a RouteDefinition object based on the current renderModel /// </summary> /// <param name="requestContext"></param> /// <param name="publishedContentRequest"></param> /// <returns></returns> internal virtual RouteDefinition GetUmbracoRouteDefinition(RequestContext requestContext, PublishedContentRequest publishedContentRequest) { var defaultControllerType = DefaultRenderMvcControllerResolver.Current.GetDefaultControllerType(); var defaultControllerName = ControllerExtensions.GetControllerName(defaultControllerType); //creates the default route definition which maps to the 'UmbracoController' controller var def = new RouteDefinition { ControllerName = defaultControllerName, ControllerType = defaultControllerType, PublishedContentRequest = publishedContentRequest, 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) { //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(); 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); //check if that controller exists if (controllerType != null) { //ensure the controller is of type 'IRenderMvcController' and ControllerBase if (TypeHelper.IsTypeAssignableFrom <IRenderMvcController>(controllerType) && TypeHelper.IsTypeAssignableFrom <ControllerBase>(controllerType)) { //set the controller and name to the custom one def.ControllerType = controllerType; def.ControllerName = ControllerExtensions.GetControllerName(controllerType); if (def.ControllerName != defaultControllerName) { def.HasHijackedRoute = true; } } else { LogHelper.Warn <RenderRouteHandler>( "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, () => controllerType.FullName, () => typeof(IRenderMvcController).FullName, () => typeof(ControllerBase).FullName); //exit as we cannnot route to the custom controller, just route to the standard one. return(def); } } //store the route definition requestContext.RouteData.DataTokens["umbraco-route-def"] = def; return(def); }