Umbraco does not respond to any URL with an extension (eg. apple.banana)

We ran into a problem while trying to get our installations to respond to the URL sitemap.xml. We resolved that with a setting in appsettings, “TryMatchingEndpointsForAllPages” and a redirect like this:

	<rule name="Sitemap Redirect" enabled="true">
		<match url="sitemap.xml" ignoreCase="true" />
		<action type="Rewrite" url="sitemap-xml" appendQueryString="false" />
	</rule>

BUT… during our testing, that raised another problem: Any URL with an extension (text after a period) would generate a 404 page that is not captured and run through Umbraco’s pipeline. For instance, if you go to https://umbraco.com/apple you will get a nice content managed 404 page. But if you go to https://umbraco.com/apple.banana you will get the ugly non-umbraco 404 page. This has happened on all of our installations and it concerned us.

With umbraco documentation AND some added tweaking, we have finally come up with a solution that makes us feel resolved. First create a route that answers to /error

using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core.Models.PublishedContent;
using Umbraco.Cms.Web.Common;

namespace www.Utilities.Controllers;

public class ErrorController : Controller
{
    private UmbracoHelper _umbracoHelper;
    public ErrorController(
        UmbracoHelper umbraco)
    {
        _umbracoHelper = umbraco;
    }

    [Route("error/{statusCode}")]
    [Route("error")]
    public IActionResult HandleError([FromRoute] int? statusCode)
    {
        IPublishedContent? page;
        switch (Response.StatusCode)
        {
            case StatusCodes.Status200OK:
            case StatusCodes.Status404NotFound:
                // Here is where you could get the content page that is in the appsettings
                page = _umbracoHelper.Content(new Guid("441c72d6-2e5e-4a22-8d1e-b80569012caf"));
                break;
            case StatusCodes.Status500InternalServerError:
                page = _umbracoHelper.Content(new Guid("441c72d6-2e5e-4a22-8d1e-b80569012caf"));
                break;
            default:
                page = _umbracoHelper.Content(new Guid("441c72d6-2e5e-4a22-8d1e-b80569012caf"));
                break;
        }
        if (page != null)
        {
            _umbracoHelper.AssignedContentItem = page;
            return View(page.GetTemplateAlias(), page);
        }
        return null;
    }

}

Then in the builder add these two lines (probably not when you’re running in development but that’s up to you.

    app.UseStatusCodePagesWithReExecute("/error/{0}");
    app.UseExceptionHandler("/error");

I know this is not a question, but I thought I would share a solution to a problem that has plagued us for a while (and you can see it’s on other installations like umbraco.com). We don’t post very often so if this is not the place to put this, please let me know and I’ll move it elsewhere.

4 Likes

Hi @mikeleitzel

That’s interesting, I guess it’s due to the static file middleware handling it as it has an extension rather than passing it onto Umbraco’s pipeline. I can confirm this also happens on one of my v13 sites - I had never considered this before (not that it is a huge issue for me).

Thanks for your solution as it may help another developer!

Justin

2 Likes

This is a nice solution to that problem. I’ve used custom middleware to fix this in the past but your approach is much cleaner and easier to implement!

With a little more work you can also make the error page lookup dynamic based on URL, which can be helpful for multi-site setups.