Skip to content

[Routing]Raw route values should be restored after template binder failing binding values when generating a url #1860

@anobaka

Description

@anobaka

Minimal repro steps

  1. Create a sample .net core web application.
  2. Modify the app.UseMvc... line to:
app.UseMvc(routes =>
{
    routes.MapRoute(
        name: "test",
        template: "{area?}/{controller=Home}/{action=Index}/{id?}"
    );
    routes.MapRoute(
        name: "default",
        template: "{controller=Home}/{action=Index}/{id?}");
});
  1. Add TestController and an Index action in it.
  2. Add var a = Url.Action("Index", "Test"); in Index Action of HomeController.
  3. Run app and visit /.

Expected result

local variable a should be /Test

Actual result

the value of a is /

Further technical details

I checked the source of Routing and found that the raw route values will not be restored after template binder failed binding values. So when the default router was tring to generate url, there was action:Index only left in route values, so it used the default controller Home.
ref:
https://github.com/aspnet/Routing/blob/rel/1.1.0/src/Microsoft.AspNetCore.Routing/Template/TemplateBinder.cs#L238
https://github.com/aspnet/Routing/blob/rel/1.1.0/src/Microsoft.AspNetCore.Routing/Template/TemplateBinder.cs#L279
I think the logic is that all routers should try to bind raw route values to generate url, but not the route values modified by previous router, so the raw route values should be restored after each router binding or routers should use the copy of the raw route values.

Thanks.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions