/// <inheritdoc/> public async Task ExecuteResultAsync(ActionContext context) { HttpResponse response = context.HttpContext.Response; response.Clear(); response.StatusCode = StatusCodes.Status404NotFound; IPublishedRequest frequest = _umbracoContext.PublishedRequest; var reason = "Cannot render the page at URL '{0}'."; if (frequest.HasPublishedContent() == false) { reason = "No umbraco document matches the URL '{0}'."; } else if (frequest.HasTemplate() == false) { reason = "No template exists to render the document at URL '{0}'."; } var viewResult = new ViewResult { ViewName = "~/umbraco/UmbracoWebsite/NotFound.cshtml" }; context.HttpContext.Items.Add("reason", string.Format(reason, WebUtility.HtmlEncode(_umbracoContext.OriginalRequestUrl.PathAndQuery))); context.HttpContext.Items.Add("message", _message); await viewResult.ExecuteResultAsync(context); }
private string?GetTemplateName(IPublishedRequest request) { // 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. return(request.GetTemplateAlias()?.Split('.')[0].ToSafeAlias(_shortStringHelper)); } return(null); }
/// <summary> /// Special check for when no template or hijacked route is done which needs to re-run through the routing pipeline /// again for last chance finders /// </summary> private async Task <UmbracoRouteValues> CheckNoTemplateAsync( HttpContext httpContext, UmbracoRouteValues def, bool hasHijackedRoute) { IPublishedRequest request = def.PublishedRequest; // Here we need to check if there is no hijacked route and no template assigned but there is a content item. // If this is the case we want to return a blank page. // We also check if templates have been disabled since if they are then we're allowed to render even though there's no template, // for example for json rendering in headless. if (request.HasPublishedContent() && !request.HasTemplate() && !_umbracoFeatures.Disabled.DisableTemplates && !hasHijackedRoute) { IPublishedContent?content = request.PublishedContent; // This is basically a 404 even if there is content found. // We then need to re-run this through the pipeline for the last // chance finders to work. // Set to null since we are telling it there is no content. request = await _publishedRouter.UpdateRequestAsync(request, null); if (request == null) { throw new InvalidOperationException( $"The call to {nameof(IPublishedRouter.UpdateRequestAsync)} cannot return null"); } string?customActionName = GetTemplateName(request); def = new UmbracoRouteValues( request, def.ControllerActionDescriptor, customActionName); // if the content has changed, we must then again check for hijacked routes if (content != request.PublishedContent) { def = CheckHijackedRoute(httpContext, def, out _); } } return(def); }
private PublishedContentNotFoundResult GetNoTemplateResult(IPublishedRequest pcr) { // 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()) { // means the builder could not find a proper document to handle 404 return(new PublishedContentNotFoundResult(UmbracoContext)); } if (!pcr.HasTemplate()) { // means the engine could find a proper document, but the document has no template // at that point there isn't much we can do return(new PublishedContentNotFoundResult( UmbracoContext, "In addition, no template exists to render the custom 404.")); } return(new PublishedContentNotFoundResult(UmbracoContext)); }
/// <inheritdoc/> public async Task ExecuteResultAsync(ActionContext context) { HttpResponse response = context.HttpContext.Response; response.Clear(); response.StatusCode = StatusCodes.Status404NotFound; IPublishedRequest frequest = _umbracoContext.PublishedRequest; var reason = "Cannot render the page at URL '{0}'."; if (frequest.HasPublishedContent() == false) { reason = "No umbraco document matches the URL '{0}'."; } else if (frequest.HasTemplate() == false) { reason = "No template exists to render the document at URL '{0}'."; } await response.WriteAsync("<html><body><h1>Page not found</h1>"); await response.WriteAsync("<h2>"); await response.WriteAsync(string.Format(reason, WebUtility.HtmlEncode(_umbracoContext.OriginalRequestUrl.PathAndQuery))); await response.WriteAsync("</h2>"); if (string.IsNullOrWhiteSpace(_message) == false) { await response.WriteAsync("<p>" + _message + "</p>"); } await response.WriteAsync("<p>This page can be replaced with a custom 404. Check the <a target='_blank' href='https://umbra.co/custom-error-pages'>documentation for <a href=\"https://our.umbraco.com/Documentation/Tutorials/Custom-Error-Pages/#404-errors\" target=\"_blank\">Custom 404 Error Pages</a>.</p>"); await response.WriteAsync("<p style=\"border-top: 1px solid #ccc; padding-top: 10px\"><small>This page is intentionally left ugly ;-)</small></p>"); await response.WriteAsync("</body></html>"); }
/// <inheritdoc /> public async Task <UmbracoRouteValues> CreateAsync(HttpContext httpContext, IPublishedRequest request) { if (httpContext is null) { throw new ArgumentNullException(nameof(httpContext)); } if (request is null) { throw new ArgumentNullException(nameof(request)); } string?customActionName = null; // 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. customActionName = request.GetTemplateAlias()?.Split('.')[0].ToSafeAlias(_shortStringHelper); } // The default values for the default controller/action var def = new UmbracoRouteValues( request, _defaultControllerDescriptor.Value, customActionName); def = CheckHijackedRoute(httpContext, def, out var hasHijackedRoute); def = await CheckNoTemplateAsync(httpContext, def, hasHijackedRoute); return(def); }