39

I understand that RoutePrefix doesn't add a route to the routing table by itself. On your actions you need to have a Route attribute declared. I am having a hard time finding an authoritative blog/msdn page/ something that states why by defalut RoutePrefix doesn't add a route to the routing table.

Does anyone have an authoritative post that does contain this to be the case, and if so will you let me know whom it is. Thank you very much.

Edit To Clarify my question

DOESN'T WORK

[RoutePrefix("api/Steve")]
public class SteveController : ApiController
{
    public int get(){return 1000000;}
}

Works

[RoutePrefix("api/Steve")]
public class SteveController : ApiController
{
    [Route("")]
    public int get(){return 1000000;}
}

The above scenario works because we explicitly stated that the get action on the SteveController has an empty route. Once we do that the route is added to the RouteTable

The first scenario doesn't work, because just using RoutePrefix doesn't add anything to the route table. RoutePrefix by itself will not generate a route. This seems to be common knowledge, I want to find a trusted source, like official Microsoft documentation, that states why this is.

ruffin
  • 16,507
  • 9
  • 88
  • 138
gh9
  • 10,169
  • 10
  • 63
  • 96

3 Answers3

28

Route prefixes are associated with routes by design in attribute routing.

It is used to set a common prefix for an entire controller.

If you read the release notes that introduced the feature you may get a better understanding of the subject.

ASP.NET Web API 2

Attribute routing

ASP.NET Web API now supports attribute routing, thanks to a contribution by Tim McCall. With attribute routing you can specify your Web API routes by annotating your actions and controllers like this:

[RoutePrefix("orders")] 
public class OrdersController : ApiController 
{ 
    [Route("{id}")] 
    public Order Get(int id) { } 
    [Route("{id}/approve")] 
    public Order Approve(int id) { } 
} 

Attribute routing gives you more control over the URIs in your web API. For example, you can easily define a resource hierarchy using a single API controller:

public class MoviesController : ApiController 
{ 
    [Route("movies")] 
    public IEnumerable<Movie> Get() { } 
    [Route("actors/{actorId}/movies")] 
    public IEnumerable<Movie> GetByActor(int actorId) { } 
    [Route("directors/{directorId}/movies")] 
    public IEnumerable<Movie> GetByDirector(int directorId) { } 
} 

What's New in ASP.NET Web API 2.1

What's New in ASP.NET Web API 2.2

A really good article on the subject

ASP.NET 5 Deep Dive: Routing

While no expert on the subject, here is my understanding of how this works.

With attribute routing the framework inspects the route attribute on the actions of a controller in order to create route entries to add to the route table. So as long as you are using attribute routing you are going to be using the [RouteAttribute]. Without this attribute the action will default back to convention-based routing. The RoutePrefixAttribute is an extensibility point that allows you more control of how you define your routes/Urls. The release notes say as much.

Other than my understanding and the last link provided, everything else was quoted from MS documentation.

Nkosi
  • 235,767
  • 35
  • 427
  • 472
  • 1
    These articles are extremely good and are great for understanding the basics, they do not address my question though – gh9 Apr 11 '16 at 20:05
  • 1
    But the definition of the `RoutePrefix` basically already explains why it only works with a rout. It is used to store `common` prefix among the routes in the controller. – Nkosi Apr 11 '16 at 20:07
  • my question isnt why does it work. It is ***I would like to see some source that states that.*** To my knowledge and googlefu it is just common information that everyone has. – gh9 Apr 11 '16 at 20:12
  • 2
    Up-voted you...but wanted to add in 2023 ASP.NET Core, they got rid of RoutePrefix, as its part of the old WebAPI 2 library (Microsoft.AspNet.WebApi.Core). In ASP.NET Core 7 they MERGED both MVC and WebAPI into one new MVC master library for both that now has a model, close to the same, but just uses "[Route]". Example: MVC Controller Attributes are optional and now look like this: [Route("[controller]/[action]")] (default route) and WebAPI attributes are not optional and look like this: [ApiController][Route("api/[controller]")] (webapi always use attributes) lol anyone else still confused? – Stokely Jan 28 '23 at 14:40
18

For an authoritative source, here are the descriptions from MSDN (emphasis mine).

RouteAttribute

Place on a controller or action to expose it directly via a route. When placed on a controller, it applies to actions that do not have any System.Web.Mvc.RouteAttribute’s on them.

RoutePrefixAttribute

Annotates a controller with a route prefix that applies to all actions within the controller.

As you can see, the description for Route mentions exposing the action(s), but RoutePrefix does not.

Robert Dennis
  • 301
  • 2
  • 4
0

RoutePrefix attribute is used to specify the common route prefix at the controller level. It eliminates common route prefix on every controller method. Route attribute is used to specify the route at the method level in controller. Each method in controller has its own unique route.

Let's understand by code

Code without RoutePrefix attribute: You can see prefix "api/students" is repeating with each method in controller.

public class StudentsController : ApiController
{
    [Route("api/students/{id}")]
    public Student Get(int id) 

    [Route("api/students/{id}/courses")]
    public IEnumerable<string> GetStudentCourses(int id)
}

Code with RoutePrefix attribute: You can see RoutePrefix eliminate the use of prefix at method level by using it at controller level)

[RoutePrefix("api/students")]
public class StudentsController : ApiController
{
    [Route("{id}")]
    public Student Get(int id) 

    [Route("{id}/courses")]
    public IEnumerable<string> GetStudentCourses(int id)
}
Billu
  • 2,733
  • 26
  • 47