0

In WebAPI you can specify an Order in RouteAttribute to determine which order the routes are matched in. For example the below will match /other to GetOther before matching /blah to GetByName

[HttpGet, Route("{name}", Order = 1)]
public string GetByName(string name) { ... }

[HttpGet, Route("other")]
public string GetOther() { ... }

How would I do the same but with RoutePrefix (which doesn't have an Order property)? If it did it would looks something like this:

[RoutePrefix("foo", Order = 1)]
public class FooController : ApiController { ... }

[RoutePrefix("foo/bar")]
public class FooBarController : ApiController { ... }

Doing the above (without the imaginary Order property) throws the following message when calling /foo/bar:

Multiple controller types were found that match the URL

Is there existing functionality for getting around this (preferably with attributes)?

danludwig
  • 46,965
  • 25
  • 159
  • 237
dav_i
  • 27,509
  • 17
  • 104
  • 136
  • To be perfectly honest, even though I answered this question, it doesn't really make sense to me. `RoutePrefix` does not declare a route in and of itself, so it cannot have any `Order`. Instead, it is prefixed to all route-attributed actions in its controller. So you can't Order it, since it's only a prefix. Unless you are saying you want all routes with that prefix (meaining in that controller) to be registered before routes with another prefix (in a different controller). My point is you would need a different attribute altogether, like `RoutingPrecedenceAttribute` which could have `Order`. – danludwig Feb 27 '15 at 17:16

2 Answers2

2

I don't believe Microsoft's attribute routing has support for ordering routes by controller.

When you specify an Order property on an action's RouteAttribute, you are specifying the order within the controller only.

AFAIK, the attribute routing algorithm will scan all of the controllers alphabetically. Then within each controller, is will use the Order property of any RouteAttributes to decide the order of action routes within that controller.

This means if you have route collisions spread across different controllers, you should either rethink the design or make sure the controllers with the more specific route patterns are named alphabetically before the controllers with the more general route patterns. Otherwise, you may run into that "ambiguous route / multiple actions with matching routes found" exception.

Update: The answer above is for Microsoft's AttributeRouting implementation, which was based on another very popular open source project that came before MVC5. In that library, you could order attribute routes by controller, though I think the property was SiteOrder or something like that.

danludwig
  • 46,965
  • 25
  • 159
  • 237
  • Do you mean I could (in theory but it's a bit disgusting) do `AFooBarController` and `BFooController` with the `[RoutePrefix]`es as above? – dav_i Feb 27 '15 at 17:03
  • @dav_i yes I think you could. Try it out, see if it fixes the problem you are trying to solve. Putting it in a different folder or namespace that comes alphabetically first may also do the trick. – danludwig Feb 27 '15 at 17:04
0

You can add a orderby to the loop in index.cshtml:

@foreach (var group in apiGroups.OrderBy(g => g.Key.ControllerName))
Machavity
  • 30,841
  • 27
  • 92
  • 100
Tim
  • 1