/// <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);
        }
Ejemplo n.º 2
0
    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);
    }
Ejemplo n.º 3
0
    /// <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);
    }
Ejemplo n.º 4
0
    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));
    }
Ejemplo n.º 5
0
        /// <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>");
        }
Ejemplo n.º 6
0
    /// <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);
    }