aspnet / Routing

[Archived] Middleware for routing requests to application logic. Project moved to https://github.com/aspnet/AspNetCore
Apache License 2.0
272 stars 122 forks source link

Difference in rejected outbound route constraint behavior compared to 2.1 and endpoint routing #862

Closed pranavkm closed 5 years ago

pranavkm commented 5 years ago

I have an IRouteConstraint like so:

public class EvenRouteConstraint : IRouteConstraint
{
    /// <inheritdoc />
    public bool Match(
        HttpContext httpContext,
        IRouter route,
        string routeKey,
        RouteValueDictionary values,
        RouteDirection routeDirection)
    {
        if (values.TryGetValue(routeKey, out var value) && value != null)
        {
            var valueString = Convert.ToString(value, CultureInfo.InvariantCulture);
            return int.TryParse(valueString, out var result) && result % 2 == 0;
        }

        return false;
    }
}

The action:

[HttpGet("/[controller]/[action]/{id:even}")]
public IActionResult Index(int id) => View("/Pages/Index.cshtml");

and the view:

@Url.Action("Index", new { id = 2 })
@Url.Action("Index", new { id = 3 })

With 2.1 routing, the output is so:

/Home/Index/2 /Home/Index/3

With 2.2 routing, the output is so:

/Home/Index/2

Might be the same thing as https://github.com/aspnet/Routing/issues/728. Filing this so we're aware of the difference in behavior.

rynowak commented 5 years ago

Does you application also have a conventional route? I don't understand how you're setting that result in 2.1

pranavkm commented 5 years ago

Does you application also have a conventional route?

Yup, there's a conventional route with the default template. Removing it makes the two versions behave identically.

rynowak commented 5 years ago

hmm that's interesting, I would expect the link generator to see both templates.

rynowak commented 5 years ago

OK. this is definitely expected behaviour in 2.2

What's happening is that in the 2.1 case the conventional route (without constraint) can successfully generate a URL - because that's what conventional routes do.

Conventional routes in endpoint routing don't link to actions that don't exist.