0

I am trying to setup a dynamic route catch-all so that all routes that do not match the hardcoded routes gets sent to DynamicRouteValueTransformer which tries to find the dynamic route in the database.

The issue I'm having is that this catch-all is getting first evaluated on all requests, even for static files like .js or .css. How can I fix this?

Startup/Configure

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseWebOptimizer();
    app.UseHttpsRedirection();
    app.UseCookiePolicy();
    app.UseRouting();
    app.UseAuthentication();
    app.UseAuthorization();
    app.UseSession();

    app.UseEndpoints(endpoints =>
    {
        // Secure-route.
        endpoints.MapAreaControllerRoute(name: "secure-route", areaName: "Secure", pattern: "Secure/{controller=Dashboard}/{action=index}/{id?}");

        // Startpage
        endpoints.MapControllerRoute(name: "default", pattern: "{controller=Home}/{action=Index}");

        endpoints.MapControllerRoute(name: "Orders", pattern: "{controller=Orders}/{action=Index}");

        // Razorpages for identity
        endpoints.MapRazorPages();

        // Catch-all for cms-routes
        endpoints.MapDynamicControllerRoute<CustomRouteTransformer>("{**slug}");
    });
}

DynamicRouteValueTransformer-code:

public class CustomRouteTransformer : DynamicRouteValueTransformer
{
    private readonly IRouteProjectionService _routeService;

    public CustomRouteTransformer(IRouteProjectionService routeService)
    {
        _routeService = routeService;
    }

    public override ValueTask<RouteValueDictionary> TransformAsync(HttpContext httpContext, RouteValueDictionary values)
    {
        // Get contentpage based on URL
        var url = httpContext.Request.Path.ToString();
        var contentPage = _routeService.GetRoute(url).Result;

        values["controller"] = contentPage.Controller;
        values["action"] = contentPage.Action;
        values["viewName"] = contentPage.View;
        values["pageId"] = contentPage.Id;

        return new ValueTask<RouteValueDictionary>(values);
    }
}

RouteProjectionService:

public class RouteProjectionService : IRouteProjectionService
{
    private readonly IAsyncRepository<ContentPage> _contentPageRepository;
    private readonly IAsyncRepository<PageTemplate> _pageTemplateRepository;
    private readonly ILogger<RouteProjectionService> _logger;
    public RouteProjectionService(IAsyncRepository<ContentPage> contentPageRepository,
                                  IAsyncRepository<PageTemplate> pageTemplateRepository,
                                  ILogger<RouteProjectionService> logger)
    {
        _contentPageRepository = contentPageRepository;
        _pageTemplateRepository = pageTemplateRepository;
        _logger = logger;
    }
    public async Task<RouteProjection> GetRoute(string url)
    {
        try
        {
            var spec = new ContentPageAndRouteSpecificationByUrl(url);
            var contentPage = await _contentPageRepository.FirstOrDefaultAsync(spec);
            if (contentPage == null)
            {
                _logger.LogError("No contentpage found");
                return null;
            }
            
            var projection = new RouteProjection
            {
                Url = contentPage.Url,
                Name = contentPage.PageTemplate.Name,
                Id = contentPage.Id,
                Action = contentPage.PageTemplate.Action,
                Controller = contentPage.PageTemplate.Controller,
                View = contentPage.PageTemplate.View,
                ContentPageType = contentPage.PageTemplate.ContentPageType
            };

            return projection;
        }
        catch (Exception ex)
        {
            throw new Exception("error setting up routes", ex.InnerException);
        }
    }
}
klas mack
  • 589
  • 7
  • 23
  • Could you please share your `IRouteProjectionService` which could help reproduce your issue? – Rena Oct 15 '20 at 07:56
  • the issue is that the catch-all route DynamicRouteValueTransformer seems to catch all requests, so the route order does not work. Even if I remove the IRouteProjectionService its still the same – klas mack Oct 15 '20 at 08:09
  • `Even if I remove the IRouteProjectionService its still the same`.Of course.But I need reproduce your issue.How did you know the order does not work?Did you use the matched url for one of the route template but it still get into the CustomRouteTransformer? – Rena Oct 15 '20 at 08:17
  • Makes sense, thank you! :-) I Edited the question to include. It seems the dynamic route does not respect route order since its executed on each request regardless of the route – klas mack Oct 15 '20 at 08:40

0 Answers0