简体   繁体   中英

Dynamic routing in ASP.NET Core 3.1 when part of the url is already another route

I'm trying to use DynamicRouteValueTransformer with IEndpointRouteBuilder.MapDynamicControllerRoute to dynamically map new routes. This is for pages that are added while the application is running.

I'm doing:

endpoints.MapDynamicControllerRoute<RouteValueTransformer>("{**slug}");

to catch all urls that don't already have a route assigned, so that RouteValueTransformer can try to find one when necessary. By putting a breakpoint inside the RouteValueTransformer.TransformAsync method, I can see when it runs. If you just type any nonsense url in, it will enter the method as expected. For a url that doesn't have a route assigned, but an earlier part of the url does , it won't enter the method, as it seems to think it already has a route, but then it obviously gives a 404 error.

For example, if after the above line I do

endpoints.MapControllerRoute(
   name: "test",
   pattern: "category/product1",
   defaults: new { controller = "Home", action = "Index" });

and then try to browse to "category/product2", I think it should enter the TransformAsync method to try and find a route, but it doesn't, and it gives a 404. If you change "category" to something else, it will enter the method.

I'm not sure if this is expected behaviour, a bug, or if I'm using the "pattern" parameter wrong, or maybe {**slug} wrong?

To reproduce

It's very easy to reproduce. Create a new ASP.NET Core 3.1 web application. Add

app.UseEndpoints(endpoints =>
{
    var defaults = new { controller = "Home", action = "Index" };
    endpoints.MapControllerRoute(name: "test", pattern: "category/product1", defaults: defaults);
    endpoints.MapDynamicControllerRoute<RouteValueTransformer>("{**slug}");
});

to the end of Startup.Configure ,

services.AddSingleton<RouteValueTransformer>();

to Startup.ConfigureServices , and

public class RouteValueTransformer : DynamicRouteValueTransformer
{
    public override async ValueTask<RouteValueDictionary> TransformAsync(HttpContext httpContext, RouteValueDictionary values)
    {
        return values;
    }
}

and set a breakpoint on return values; to see when it runs.

What else I've tried

endpoints.MapDynamicControllerRoute<RouteValueTransformer>("{one}/{two}"); - also doesn't enter method.

Looking through documentation. There isn't much on DynamicRouteValueTransformer (yet) unfortunately so I've found it quite difficult.

Update

I'm starting to think that it is mostly likely a bug, so I've raised this Github issue

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM