Matching and Rebuilding URL Routes in ASP.NET Core

96 views Asked by At

I'm working on an ASP.NET Core application where I have a default route template, for example: ~/api/{area}/[controller]/{action?}/{id?}.

My goal is to match incoming URLs with other route templates and dynamically reconstruct them with the default route template when no direct match is found.

Consider a scenario where someone sends a request like ~/{area}/api/[controller]/{action?}/{id?}. The first call to app.UseRouting(), EndpointRoutingMiddleware doesn't find any match.

In such cases, I want to rebuild the path dynamically to match my default route template (~/api/{area}/[controller]/{action?}/{id?}) and then trigger app.UseRouting() again to find the correct endpoint.

Startup.cs;

app.UseRouting();

app.UseMiddleware<RoutingMatcherMiddleware>();

app.UseRouting();

Middleware;

public Task Invoke(HttpContext context)
{
    var endpointFeature = context.Features[typeof(IEndpointFeature)] as IEndpointFeature;
    var endpoint = endpointFeature?.Endpoint;

    if (endpoint != null)
    {
        return _next(context);
    }

    //My other route templates that I didn't define on my BaseApiController
    foreach (var routeTemplate in _routeTemplates)
    {
        var templateParser = TemplateParser.Parse(routeTemplate);
        var matcher = new TemplateMatcher(templateParser, null);
        var values = new RouteValueDictionary();
        if (matcher.TryMatch(context.Request.Path, values))
        {
            context.Request.Path = ReBuildRequestPath(context.Request.Path, values);
            break;
        }
    }

    return _next(context);
}

But this logic doesn't work properly since the second UseRouting overrides the request pipeline and the first one is completely ignored. And situation causes that endpoint is always null here;

if (endpoint != null)
{
    return _next(context);
}

In sum, my custom matcher is executed for every request regardless it is matched with my default template or not.

Same problem mentioned here as well;

https://github.com/dotnet/aspnetcore/issues/17210

Any idea about alternative solutions/ideas ?

Note: I am restricted to define all possible route templates on my BaseApiController due to performance issue on .NET 5 and this is why I am looking for a dynamic solution;

https://github.com/dotnet/aspnetcore/issues/30092

0

There are 0 answers