-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Consider changing Attribute Route behavior with areas + ambient values #1913
Description
Right now, link generation for attribute routes when using areas behaves very similarly to conventional routing. Much like conventional routing, when you have duplicate action and controller names you must either:
1). Be explicit about route when generating links (always specify the area token)
2). Use order to configure the desired precedence.
Example follows...
The question is.. do we want this behavior to be smarter than conventional routing? We might be able to implement something good here. There's a small tuning change we could make to this algorithm to make this work as-desired without the need for setting an order.
Example: Consider the following conventionally routed controllers:
namespace MvcSample.Web1
{
[Area("A1")]
public class RoutingTest : Controller
{
public string Action()
{
return Url.Action();
}
}
}
namespace MvcSample.Web2
{
public class RoutingTest : Controller
{
public string Action()
{
return Url.Action();
}
}
}
with routes
routes.MapRoute("areaRoute", "{area:exists}/{controller}/{action}");
routes.MapRoute("controllerActionRoute", "{controller}/{action}",);
Each of these actions tries to link to itself, using only ambient values. If the routes are ordered as-is, then this will work as expected.
http://localhost:5001/A1/RoutingTest/Action -> http://localhost:5001/A1/RoutingTest/Action
http://localhost:5001/RoutingTest/Action -> http://localhost:5001/RoutingTest/Action
However, if you switch the route ordering, then the controllerActionRoute
is too greedy.
http://localhost:5001/A1/RoutingTest/Action -> http://localhost:5001/RoutingTest/Action
http://localhost:5001/RoutingTest/Action -> http://localhost:5001/RoutingTest/Action
This is an inherent issue in conventional routing. You get the same issue with attribute routes when you have a duplicate action/controller. Order is needed to resolve the problem (if you're relying on ambient values).
Ex:
namespace MvcSample.Web3
{
[Area("A2")]
[Route("A2/[controller]/[action]")]
public class AttributeRoutingTest : Controller
{
public string Action()
{
return Url.Action();
}
}
}
namespace MvcSample.Web4
{
[Route("[controller]/[action]", Order = 1)]
public class AttributeRoutingTest : Controller
{
public string Action()
{
return Url.Action();
}
}
}