If I understand your question correctly, I would say it is because you generally don't have explicit control over the parameters passed to an action.
Remember that the model binding will, by default, take them from a number of different places, including ones that are outside your control, like querystring.
It sounds like you're thinking that you should be able to have something like this:
/article/list/sport
Which calls ArticleController.List(string category);
And also:
/article/list/sport/20110901
Which calls ArticleController.List(string category, DateTime date);
But what happens when someone types the URL /article/list/sport?date=20110902
?
It just sounds like a recipe for unpredictable behaviour, and in return, what real benefit would you get from this sort of action overloading?
Generally, you want your Controllers to do only a few things:
- Handle the incoming request
- Delegate the processing to some business object
- Pass the result of the business processing to the appropriate view for rendering
There shouldn't be any data access or complex business logic in the controller.
[In the simplest of apps, you can probably get away with basic data CRUD actions in your controller, but once you start adding in more than simple Get and Update calls, you are going to want to break out your processing into a separate class.]
Your controllers will usually depend on a 'Service' to do the actual processing work. In your service class you may work directly with your data source (in your case, the DbContext), but once again, if you find yourself writing a lot of business rules in addition to the data access, you will probably want to separate your business logic from your data access.
At that point, you will probably have a class that does nothing but the data access. Sometimes this is called a Repository, but it doesn't really matter what the name is. The point is that all of the code for getting data into and out of the database is in one place.
For every MVC project I've worked on, I've always ended up with a structure like:
Controller
public class BookController : Controller
{
ILibraryService _libraryService;
public BookController(ILibraryService libraryService)
{
_libraryService = libraryService;
}
public ActionResult Details(String isbn)
{
Book currentBook = _libraryService.RetrieveBookByISBN(isbn);
return View(ConvertToBookViewModel(currentBook));
}
public ActionResult DoSomethingComplexWithBook(ComplexBookActionRequest request)
{
var responseViewModel = _libraryService.ProcessTheComplexStuff(request);
return View(responseViewModel);
}
}
Business Service
public class LibraryService : ILibraryService
{
IBookRepository _bookRepository;
ICustomerRepository _customerRepository;
public LibraryService(IBookRepository bookRepository,
ICustomerRepository _customerRepository )
{
_bookRepository = bookRepository;
_customerRepository = customerRepository;
}
public Book RetrieveBookByISBN(string isbn)
{
return _bookRepository.GetBookByISBN(isbn);
}
public ComplexBookActionResult ProcessTheComplexStuff(ComplexBookActionRequest request)
{
// Possibly some business logic here
Book book = _bookRepository.GetBookByISBN(request.Isbn);
Customer customer = _customerRepository.GetCustomerById(request.CustomerId);
// Probably more business logic here
_libraryRepository.Save(book);
return complexBusinessActionResult;
}
}
Repository
public class BookRepository : IBookRepository
{
LibraryDBContext _db = new LibraryDBContext();
public Book GetBookByIsbn(string isbn)
{
return _db.Books.Single(b => b.ISBN == isbn);
}
// And the rest of the data access
}
Best Answer
I think you got it all wrong regarding Web Services... Your page methods analogy is correct, but web services is a whole other ball game.
Here is a small, yet to the point, explanation on why use web services:
http://www.w3schools.com/webservices/ws_why.asp
Wikipedia's definition for Web Services also gives you an insight into why they are used.
There are many reasons, but the main one, I would say, is interoperability.
But, yeah, if all you used web services for was to use jQuery to call a method directly, then you probably shouldn't use web services...