Are your ASP.NET MVC URLs consistent?

Over the past couple of months, I’ve finally started work on my first web application built using the ASP.NET MVC framework. It’s going pretty well now, but at the start, in typical fashion, I spent more time googling and trawling message boards than actually cutting code.

My first head-scratching moment was around the naming of controllers and actions that form the path at the end of a URL. Specifically:

  • Are controller names plural or singular?
  • In a route, which comes first; the ID or the action?
  • Should I call this action add, create, insert or new?

Don’t laugh. This stuff will come as naturally as breathing to Rails developers — in fact, all of those decisions are already made for you if you use a tool like the scaffold generator to stub your code out. But with ASP.NET MVC, insufficient guidance over these sorts of choices leads to uncertainty, which leads to indecision, which leads to me mass-refactoring entire projects while I obsess over getting my object names perfect.

As you can imagine, this sort of thing is something I prefer to avoid. Luckily, some people far brighter and more experienced have already thought about this stuff, and have answers for all of my questions.

Are controller names plural or singular?

The ASP.NET MVC Framework uses a REST-based request model; instead of serving up files, it serves up resources. Resources are abstract concepts that together – like articles on Wikipedia or videos on Youtube – comprise an application’s content.

Such resources are stored in repositories, which are implemented in ASP.NET MVC as controllers.

Repository names are plural – they represent a collection of objects. For example, you might have a controller called Products. A Product – singular – is the type of resource it serves. It’s similar to the name you’d give an array or database table.

What order do I put the URL parameters?

I can’t find any reason why you’d want to deviate from the default here, although I did briefly try an OO-inspired controller/id/action route before I realised what was happening.

ASP.NET MVC is the same as Rails: first comes the controller name, then the action, then the ID of the resource in question:

Some people have suggested additional standard parameters you might like to put after this. One is pagination – if you split a list (e.g. search results) across several pages:

And another is alternative representation formats (e.g. RSS, XML, CSV etc):

If the output of your action can be represented in different formats, I think this a pretty neat way of specifying which one you want.

How do I name my controller actions?

This depends on what Route Handler you’re using. If you’re using Adam Tybor‘s Simply Restful Routing, then the decision is made for you – the action names are copied from Rails.

However, if you’re using the ASP.NET MVC default, you’ve got a bit more freedom. Stephen Walter, a product manager and ASP.NET MVC guru at Microsoft has come up with a series of standard controller action names. These are based loosely on the seven Rails controller actions, but exclude HTTP PUT and DELETE verbs, which aren’t supported by the default ASP.NET MVC route handler. They are as follows:

Controller Action HTTP verb Description
Detail GET Displays a single resource such as a database record.
Index GET Displays a collection of resources.
Create GET Displays a form for creating a new resource.
Insert POST Inserts a new resource into the repository.
Edit GET Displays a form for editing an existing resource.
Update POST Updates an existing resource.
Destroy GET Displays a page that confirms whether or not you want to delete a resource.
Delete POST Deletes a resource.

He also suggests some actions for non resource-based controllers – e.g. Home:

Controller Action HTTP verb Description
Login GET Displays a login form.
Authenticate POST Authenticates a user name and password.
Logout POST Logs out a user.

If you follow these guidelines, you will have a consistent and predictable URL format. Enforcing a standard URL format means less decision to make during development, and makes things clearer for end-users.