简体   繁体   中英

ASP.NET Core: Is there a way to make UrlHelper functions (Url.Action, etc.) work with dynamic routing?

This is .NET Core 3.1 (tried with 5.0 and 6.0 as well with the same results).

I'm trying to switch to dynamic routing for our application, which works, but it results in all Url.Action() calls through the application returning null.

Tried it in a sample app with the same results. So in Startup.cs instead of using endpoints.MapControllerRoute(...) I call endpoints.MapDynamicControllerRoute(...). For example:

            app.UseEndpoints(endpoints =>
            {
                // endpoints.MapControllerRoute(
                //     name: "default",
                //     pattern: "{controller=Home}/{action=Index}/{id?}");

                endpoints.MapDynamicControllerRoute<TestSearchTransformer>("{controller=Home}/{action=Index}");
            });

where TestSearchTransformer is just simple pass through:

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

When MapControllerRoute is used call to Url.Action("Index", "Home") returns "/Home/Index" as expected, but with MapDynamicControllerRoute it returns null.

What am I missing?

Thank you.

I found a solution, that I'm not particularly excited about. Apparently, you can create your own custom UrlHelper class (based on this Overwriting UrlHelper with a CustomUrlHelper - ASP.NET CORE 2.0 ) and override Action method in it:

public override string Action(UrlActionContext actionContext)

This works, but requires you to write your own logic for generation of the link. So this is not ideal. I still wonder if there is a better approach.

Maybe you miss to register the TestSearchTransformer. Add this in your ConfigureServices:

services.AddSingleton<TestSearchTransformer>();

Below is a work demo, you can refer to it.

Startup

public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllersWithViews();
            services.AddSingleton<TestSearchTransformer>();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/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.UseHttpsRedirection();
            app.UseStaticFiles();

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                //endpoints.MapControllerRoute(
                //    name: "default",
                //    pattern: "{controller=Home}/{action=Index}/{id?}");

                endpoints.MapDynamicControllerRoute<TestSearchTransformer>("{controller=home}/{action=index}");
            });
        }
    }

TestSearchTransformer

public class TestSearchTransformer : DynamicRouteValueTransformer
    {

        public override async ValueTask<RouteValueDictionary> TransformAsync(HttpContext httpContext, RouteValueDictionary values)
        {
            return values;

        }
    }

Result: 在此处输入图像描述

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