Popular blog tags

Dynamic Routing(MapDynamicControllerRoute) in ASP.NET Core 5.x


Table of Content

Single  MapDynamicControllerRoute

Multiple MapDynamicControllerRoute


Single  MapDynamicControllerRoute

Firstly  MapDynamicControllerRoute is used for selecting a controller action,, like this:

(selecting MapDynamicPageRoute for a page handler)

app.UseEndpoints(endpoints =>


 var pattern = "{SeName}";

This maps a route of “/search/<anything>” to a class SearchValueTransformer, which is then responsible for supplying values for the controller and action.

This SeachValueTransformer class must inherit from DynamicRouteValueTransformer.

The example I am providing here is that of a service that receives some random query for a product on the URL and then decides to which controller it will be forwarded to.

A sample implementation of this class would be:


come from:https://github.com/nopSolutions/nopCommerce/blob/12dd4825dfb56bbc64e192cd35d25e3205427646/src/Presentation/Nop.Web.Framework/Mvc/Routing/SlugRouteTransformer.cs nop4.4

using Microsoft.AspNetCore.Mvc.Routing;// for DynamicRouteValueTransformer;
class SearchValueTransformer : DynamicRouteValueTransformer
        private readonly IProductLocator _productLocator; 
        public SearchValueTransformer(IProductLocator productLocator) 
            this._productLocator = productLocator;
        public override async ValueTask TransformAsync(HttpContext httpContext, RouteValueDictionary values)
            var productString = values[“product”] as string;
            var id = await this._productLocator.FindProduct(“product”, out var controller); 
            values[“controller”] = controller; 
            values[“action”] = “Get”; 
            values[“id”] = id; 
            return values; 




 the value for page route key should be a path starting with /. So instead of "Test", you need "/Test".

public override async ValueTask<RouteValueDictionary> TransformAsync(HttpContext httpContext, RouteValueDictionary values)
   return await Task.Run(() =>
       return new RouteValueDictionary()
           { "page", "/Test" },
           { "id", "123" }



The SearchValueTransformer needs to be registered in the dependency:


The actual implementation,  it must apply some logic to the product passed in the URL to decide which controller should be used for search it, and then return some reference and a controller responsible for returning information about it. This interface and its implementation must also be registered:


Multiple MapDynamicControllerRoute


As I understand the transformers, they work like a sieve. If a transformer does not handle a route, it returns the RouteValueDictionary without modification 

// no item found
    return new RouteValueDictionary(values);

and the next registered route is checked - or in my case, the next transformer tries to handle the route. So there is (should be) no conflict.




language public class TranslationTransformer : DynamicRouteValueTransformer