Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Anders Bjerner 487 posts 2996 karma points MVP 8x admin c-trib
    Jun 29, 2021 @ 16:45
    Anders Bjerner
    0

    Intercept 404 responses for redirects package

    Hi

    I'm in the process of my redirects package.

    In Umbraco 7 and 8, the package works by adding a HTTP module that listens for all 404 responses, and then responds with a redirect if a redirect is found.

    https://github.com/skybrud/Skybrud.Umbraco.Redirects/blob/v2/latest/src/Skybrud.Umbraco.Redirects/Routing/RedirectsInjectedModule.cs#L57

    In Umbraco 9, HTTP modules have been replaced with middleware, but so far I haven't been able to accomplish the same.

    With my custom middleware, I can see that it's hit on each request, but the redirect I'm setting doesn't appear to be propagated to the user.

    https://github.com/skybrud/Skybrud.Umbraco.Redirects/blob/v3/main/src/Skybrud.Umbraco.Redirects/Middleware/RedirectsMiddleware.cs#L22

    After some help on Slack. I also had a look at RoutingRequestNotification:

    https://github.com/skybrud/Skybrud.Umbraco.Redirects/blob/v3/main/src/Skybrud.Umbraco.Redirects/Notifications/RoutingRequestNotificationHandler.cs

    This one seems to do exactly what I'm looking for, but it's only hit for requests inside the normal Umbraco request pipeline. It doesn't get hit for media or similar requests.

    So the big question is now whether there is something in Umbraco or ASP.NET I can use for this?

    The whole basis of the Umbraco 7 and 8 versions of the package is that the HTTP module allows other logic (eg. Umbraco) to run first, and then picks up any 404 responses - and then issues a HTTP redirect if a matching redirect is found in the database.

    With the middleware in Umbraco 9, it appears that if prior logic already has set a response (code), the response has been "finalized", preventing me from setting my own redirect.

  • Matt Brailsford 4125 posts 22223 karma points MVP 9x c-trib
    Jul 02, 2021 @ 11:14
    Matt Brailsford
    0

    Hey Anders,

    Have you tried in your middleware to exist the handler early and not call next? I notice in this blog post this is what he does https://weblog.west-wind.com/posts/2020/Mar/13/Back-to-Basics-Rewriting-a-URL-in-ASPNET-Core which kind of makes sense because you don't want to continue.

    Matt

  • Andy Butland 422 posts 2334 karma points MVP 4x hq c-trib
    Jul 02, 2021 @ 13:44
    Andy Butland
    1

    Is it that you you need to put your code that sets the response after the await next()? I say that as your middleware is interested in the responses, so needs to kick-in on the outgoing part.

    See this stripped down example illustrating how to log incoming requests and outgoing responses, and how the latter is after the next() call.

    Andy

  • Bjarke Berg 29 posts 265 karma points hq
    Jul 02, 2021 @ 13:51
    Bjarke Berg
    1

    Andy's answer could be a solution.

    Otherwise I guess you could do something like this, and add it after the Umbraco middleware:

     public class RedirectFromDBMiddleware
        {
            private readonly RequestDelegate _next;
            private readonly IUmbracoContextAccessor _umbracoContextAccessor;
    
            public RedirectFromDBMiddleware(RequestDelegate next, IUmbracoContextAccessor umbracoContextAccessor)
            {
                _next = next;
                _umbracoContextAccessor = umbracoContextAccessor;
            }
    
            public async Task InvokeAsync(HttpContext context)
            {
                var publishedRequest = _umbracoContextAccessor?.UmbracoContext?.PublishedRequest;
                if (publishedRequest is not null && !publishedRequest.HasPublishedContent())
                {
                    context.Response.Redirect("/whatever-for-from-db?originalUrl=" + context.Request.Path);
                }
                else
                {
                    await _next(context);
                }
    
    
            }
    
  • Anders Bjerner 487 posts 2996 karma points MVP 8x admin c-trib
    Jul 02, 2021 @ 17:10
    Anders Bjerner
    0

    Thanks Bjarke.

    Your example does handle requests inside the Umbraco request pipeline, but not for instance static files.

    I may however have missed a point about how to properly register middleware to work alongside Umbraco.

    With my updated middleware, registering it inside the WithMiddleware method, everything so far seems to work as it should - both for Umbraco and non-Umbraco requests.

    Adding the middleware directly to app, which was what I had tried earlier, doesn't work.

    image

    As this is a package for others to consume, is there a way to register the middleware automatically similar to WithMiddleware so people who install the package doesn't have to add it manually?

    I've tried various attempts by adding an IStartupFilter from my composer, which then adds the middleware, but I haven't succeeded in getting this to work.

  • Bjarke Berg 29 posts 265 karma points hq
    Jul 02, 2021 @ 18:13
    Bjarke Berg
    100

    You cann configure the UmbracoPipelineOptions..

    Kevin's example here should show you how: https://github.com/KevinJump/uSync8/blob/483a516b4847403ae4ea66f104bb1f97da81fff4/uSync.BackOffice/uSyncBackOfficeBuilderExtensions.cs#L88

  • Anders Bjerner 487 posts 2996 karma points MVP 8x admin c-trib
    Jul 02, 2021 @ 18:40
    Anders Bjerner
    0

    I even saw Kevin link to that file the other day, but hadn't thought that would apply here. But of course Kevin is on the right track:

    https://github.com/skybrud/Skybrud.Umbraco.Redirects/commit/346be8c6591235249632bdfe4afb60d1e97741c8

    Seems to work so far. Thanks again 👍

  • Bjarke Berg 29 posts 265 karma points hq
    Jul 02, 2021 @ 19:35
    Bjarke Berg
    0

    Thank you for migrating the package :)

  • This forum is in read-only mode while we transition to the new forum.

    You can continue this topic on the new forum by tapping the "Continue discussion" link below.

Please Sign in or register to post replies