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);
}
}
}