skip to Main Content

Suppose I have these actions

- http://thesite.com/Cats/product/1 
- http://thesite.com/Cats/1

My customer wants a dynamic way to define custom URL for these actions because of SEO things.
So I cant use Redirects!

Ex.

  • http://thesite.com/aaaaaa to open http://thesite.com/Cats/product/1
  • http://thesite.com/bbbbbb to open http://thesite.com/Cats/product/1, Again!
  • http://thesite.com/cccccc to open http://thesite.com/Cats/1

How do you setup routing for this dynamic behavior.
Again, I CANT USE RedirectToAction

Bests,
Thank you in advance.

2

Answers


  1. You need to create a custom DynamicRouteValueTransformer

    public class AppDynamicRouteValueTransformer : DynamicRouteValueTransformer
    {
        private readonly IList<AliasRouteMap> _aliasMaps;
    
        public AppDynamicRouteValueTransformer()
        {
            //--you can retrieve it from database table, from config....
            //--for demo I will do it manually
            _aliasMaps = new List<AliasRouteMap>(
                new[]
                {
                    new AliasRouteMap("aaaaaa", "Cats", "product", 1),
                    new AliasRouteMap("bbbbbb", "Cats", "product", 1)
                }
            );
        }
        public override async ValueTask<RouteValueDictionary> TransformAsync(HttpContext httpContext, RouteValueDictionary values)
        {
            await Task.CompletedTask;
    
            if (!values.ContainsKey("alias"))
                return values;
    
            var alias = (string)values["alias"];
    
            var aliasMap = _aliasMaps.FirstOrDefault(x => x.Alias.ToLower() == alias.ToLower());
            if (aliasMap is null)
                return values;
    
            values["controller"] = aliasMap.Controller;
            values["action"] = aliasMap.Action;
    
            if (aliasMap.Values != null)
            {
                foreach (var kvp in aliasMap.Values)
                    values[kvp.Key] = kvp.Value;
            }
    
            return values;
        }
    }
    
    public class AliasRouteMap
    {
        public AliasRouteMap(string alias, string controller, string action, object id)
            : this(alias, controller, action, new Dictionary<string, object> { { "id", id } })
        { }
    
        public AliasRouteMap(string alias, string controller, string action = "Index", IDictionary<string, object> values = null)
        {
            Alias = alias;
            Controller = controller;
            Action = action;
            Values = values;
        }
    
        public string Alias { get; set; }
        public string Controller { get; }
        public string Action { get; }
        public IDictionary<string, object> Values { get; }
    }
    

    The register the service and configure the routing in Startup class.

    ...
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddSingleton<AppDynamicRouteValueTransformer>();
        ...
    }
    
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        ...
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapDynamicControllerRoute<AppDynamicRouteValueTransformer>("{alias}");
            ...
        }
        ...
    }
    ...
    
    Login or Signup to reply.
  2. According to your description, I suggest you could also use custom middleware to achieve your requirement.

    You could check the request’s path in the custom middleware and modify the request path.

    More details, you could refer to below codes:

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Error");
            // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
            app.UseHsts();
        }
    
                app.Use(async (context, next) => {
                    if (context.Request.Path.Value.Contains("/aaaaaa")                     
                        ||context.Request.Path.Value.Contains("/bbbbbb") )
                    {
                        context.Request.Path = "/Cats/product/1";
                    }
                    if (context.Request.Path.Value.Contains("/cccccc"))
                    {
                        context.Request.Path = "/Cats/1";
                    }
    
                    await next();
                });
    
        app.UseHttpsRedirection();
        app.UseStaticFiles();
    
        app.UseRouting();
    
        app.UseAuthorization();
    
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapRazorPages();
        });
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search