Should a Controller ever need to call a Repository directly, or should it always run though the service layer? Or are there other options?
All of the examples I have been working with seem to suggest that the controller should operate on the model.
That said, I've heard some authors suggest that the model is composed of everything from business logic to data repository (as opposed to the business object classes that many consider to be the model).
Personally, I would try to keep it clean/consistent by having the controller operate on classes that operate against the repository - but I don't think there is a hard/fast rule against it.
If you have a service layer and your're using it in a way that abstracts the business logic away from the repository (as you should with a service layer) then no, your controllers should only be making calls to the service methods. The service layer will then be the coupling to the repo.
Further to Mayo's answer: the model are the data classes that will be passed throughout the application (repo, service and UI/controllers) so the UI/web layer should 'operate' on them just like the other layers will.
I think if you implement a service layer in the context of Fowler's definition and the modern aspnet mvc adaptions, then you should have your controller actions designed as very small and lightweight methods, calling the 'meaty' business logic from your service layer.
EDIT: I guess i wasn't clear: I'm not saying having a service layer is the only option, just trying to answer part of the question pertaining to the case where you do use a service layer. Agreed, a service layer is not always necessary, especially for smaller projects.
The controller interprets user input and prepares models for use by the View, as I have come to understand it. Some people are real serious about removing every bit of logic from the models, but I'm not that anal about it.
The best option IMHO is to use DI to access your repository from within the controller.
The service layer is basically an api for your business logic/business model. For example you might have some method that gets your "best customer". The service layer then does what it needs to do to query the repository, perform whatever logic it needs to do etc, and return the customer. In cases like that you should always go through the service layer.
Sometimes though you're just retrieving an object that might be in your view model, but not in the business model. Certainly you could add a wrapper around the repository in the service layer, but then you run the risk of muddying what your service layer is for and filling it with meaningless stuff. In cases like that I see no harm in going straight the repository.
You don't always need a service layer - in simple situations it is just over engineering the solution. It's fine for controller to call repository. But, if you see your controllers bloating with logic, or you are repeating yourself in controller actions, then look at putting a service between the controller and repository, and move some of the logic from the controller to ther service layer.
I would agree with @Sosh about the over engineering point. But I have found one great benefit from having the controller go through a service in that when it comes time to reuse that service over the wire via SOAP/REST your refactor work is very minimal. Keep in mind this violates YAGNI and it's thinking ahead (to some extent).
But then again - after reading the latest book by Jeffrey Palermo - MVC In Action, he has a controller with zero logic talk with a repository directly and it works just fine.