Copied to clipboard

Flag this post as spam?

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


  • João Roque 11 posts 93 karma points
    May 19, 2021 @ 08:18
    João Roque
    1

    Async Index method in Render Controller

    Hello,

    As far as I know it is not possible to perform route hijacking using a custom RenderController with an async Index method. I think it is very important to be able to do so because you usually need to load the view model with data from a DB source which in most frameworks uses async operations. You can make the async functions run sync but that is not a good practice. Is there something I'm missing? Will this be looked into in a further release?

    Meanwhile, while overriding the async Index is not possible, I'm thinking of putting my async DB functions on OnActionExecutionAsync, loading the models I need into a field on the controller and then just grabbing them in the Index method. But it would be much cleaner to do it all on Index().

    Thanks,

    João

  • David Armitage 479 posts 2008 karma points
    Jun 15, 2021 @ 07:42
    David Armitage
    0

    Hi Joao,

    Sorry I just saw this post. I wrote a blog about this a while back.

    This should be exactly what you are looking for. This is a guide how to do Route hijacking in Umbraco 9. https://www.umbrajobs.com/blog/posts/2021/june/umbraco-9-route-hijacking-custom-rendercontrollers-how-and-why/

    Let me know if you have any issues.

    Regards

    David

  • David Armitage 479 posts 2008 karma points
    Jun 15, 2021 @ 07:44
    David Armitage
    0

    Actually sorry. I didn't read correctly.

    This is more related to Async Root Hijacking.

    I will give this some more testing. Failing that this either needs logging as a bug or feature request. I would see more of a feature request than a bug.

    https://github.com/umbraco/Umbraco-CMS/issues?fbclid=IwAR2L5Dd-fjNtW251yi5Fzd-F1O6s2zhBizuhsqyptiAg4nIPDRvwVHfO6n8

    I will let you know if I manage to get this up and running.

    Regards

    David

  • João Roque 11 posts 93 karma points
    Jun 15, 2021 @ 08:12
    João Roque
    1

    Thanks for the answer David.

    As you show in your blog post Route Hijacking is still possible and easy to do in Umbraco 9, pretty much similar to Umbraco 8. The problem is if you want an async Index() method. The solution I mentioned in the orignal post works great and is not much of an hassle after all. But of course, it would be much better if we could just have an async Index() method.

    If you can put the feature request in it would be great as I have no experience doing so and I'm afraid I would mess up.

    Regards

  • Vitor Rodrigues 2 posts 73 karma points c-trib
    Jul 01, 2021 @ 20:44
    Vitor Rodrigues
    0

    Hi João,

    Ran into the same issue recently and created the following abstract class to work around the issue:

    public abstract class AsyncRenderController : RenderController
    {
        protected AsyncRenderController(ILogger<RenderController> logger, ICompositeViewEngine compositeViewEngine, IUmbracoContextAccessor umbracoContextAccessor) : base(logger, compositeViewEngine, umbracoContextAccessor)
        {
        }
    
        [NonAction]
        public sealed override IActionResult Index() => throw new NotImplementedException();
    
        public abstract Task<IActionResult> Index(CancellationToken cancellationToken);
    }
    

    The abstract class is of course not mandatory, but helps to keep the "hacky" construct hidden away. While not perfect it seems better than overriding OnActionExecutionAsync.

  • milkman matty 26 posts 108 karma points
    Oct 28, 2021 @ 10:50
    milkman matty
    0

    Hi Victor, are you able to explain exactly what this does / how it works. By marking the default, sync Index() as a [NonAction] does that route Index calls to the async Index() version?

  • Vitor Rodrigues 2 posts 73 karma points c-trib
    Oct 29, 2021 @ 07:31
    Vitor Rodrigues
    1

    That is exactly what happens.

    We mark the existing sync Index() as a [NonAction] so it isn't routable, and create a new async Index overload that will be used instead.

    The new overload needs to have a different method signature, so that's why we take a CancellationToken as a parameter, but it's fine to just not use it if not needed.

Please Sign in or register to post replies

Write your reply to:

Draft