private RouteValueDictionary HandlePostedValues(PostedDataProxyInfo postedInfo, HttpContext httpContext) { // set the standard route values/tokens var values = new RouteValueDictionary { [ControllerToken] = postedInfo.ControllerName, [ActionToken] = postedInfo.ActionName, }; ControllerActionDescriptor?surfaceControllerDescriptor = _controllerActionSearcher.Find <SurfaceController>(httpContext, postedInfo.ControllerName, postedInfo.ActionName, postedInfo.Area); if (surfaceControllerDescriptor == null) { throw new InvalidOperationException( "Could not find a Surface controller route in the RouteTable for controller name " + postedInfo.ControllerName); } // set the area if one is there. if (!postedInfo.Area.IsNullOrWhiteSpace()) { values["area"] = postedInfo.Area; } return(values); }
/// <inheritdoc/> public override async ValueTask <RouteValueDictionary> TransformAsync(HttpContext httpContext, RouteValueDictionary values) { // If we aren't running, then we have nothing to route if (_runtime.Level != RuntimeLevel.Run) { return(null); } // will be null for any client side requests like JS, etc... if (!_umbracoContextAccessor.TryGetUmbracoContext(out IUmbracoContext umbracoContext)) { return(null); } if (!_routableDocumentFilter.IsDocumentRequest(httpContext.Request.Path)) { return(null); } // Don't execute if there are already UmbracoRouteValues assigned. // This can occur if someone else is dynamically routing and in which case we don't want to overwrite // the routing work being done there. UmbracoRouteValues umbracoRouteValues = httpContext.Features.Get <UmbracoRouteValues>(); if (umbracoRouteValues != null) { return(null); } // Check if there is no existing content and return the no content controller if (!umbracoContext.Content.HasContent()) { return(new RouteValueDictionary { [ControllerToken] = ControllerExtensions.GetControllerName <RenderNoContentController>(), [ActionToken] = nameof(RenderNoContentController.Index) }); } IPublishedRequest publishedRequest = await RouteRequestAsync(umbracoContext); umbracoRouteValues = await _routeValuesFactory.CreateAsync(httpContext, publishedRequest); // now we need to do some public access checks umbracoRouteValues = await _publicAccessRequestHandler.RewriteForPublishedContentAccessAsync(httpContext, umbracoRouteValues); // Store the route values as a httpcontext feature httpContext.Features.Set(umbracoRouteValues); // Need to check if there is form data being posted back to an Umbraco URL PostedDataProxyInfo postedInfo = GetFormInfo(httpContext, values); if (postedInfo != null) { return(HandlePostedValues(postedInfo, httpContext)); } UmbracoRouteResult?routeResult = umbracoRouteValues?.PublishedRequest?.GetRouteResult(); if (!routeResult.HasValue || routeResult == UmbracoRouteResult.NotFound) { // No content was found, not by any registered 404 handlers and // not by the IContentLastChanceFinder. In this case we want to return // our default 404 page but we cannot return route values now because // it's possible that a developer is handling dynamic routes too. // Our 404 page will be handled with the NotFoundSelectorPolicy return(null); } // See https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.routing.dynamicroutevaluetransformer.transformasync?view=aspnetcore-5.0#Microsoft_AspNetCore_Mvc_Routing_DynamicRouteValueTransformer_TransformAsync_Microsoft_AspNetCore_Http_HttpContext_Microsoft_AspNetCore_Routing_RouteValueDictionary_ // We should apparenlty not be modified these values. // So we create new ones. var newValues = new RouteValueDictionary { [ControllerToken] = umbracoRouteValues.ControllerName }; if (string.IsNullOrWhiteSpace(umbracoRouteValues.ActionName) == false) { newValues[ActionToken] = umbracoRouteValues.ActionName; } return(newValues); }