I am looking at the following tutorial from Microsoft. As per this tutorial,
In the first example, “products” matches the controller named
ProductsController. The request is a GET request, so the framework
looks for a method on ProductsController whose name starts with
“Get…”. Furthermore, the URI does not contain the optional {id}
segment, so the framework looks for a method with no parameters. The
ProductsController::GetAllProducts method meets all of these
requirements.
What happens if there are two methods like GetAllProducts() and GetSoldProducts()? Both have no parameters.
Assuming you’re using the default routes the short answer is : the method defined first (at the top) of your class will be called. the other method is inaccessible.
Stealing liberally from another post I wrote on the topic:
WebAPI Matching Semantic
The matching semantic used by WebAPI is fairly simple.
So in your code sample a GET request without a parameter matches the
Get*( )function without an parameters. A Get containing and ID looks for aGet***(int id).Examples
While the matching semantic is simple, it creates some confusion for MVC developers (well at least this developer). Lets look at some examples :
Odd Names – Your get method can be named anything, so long as it starts with “get”. So in the case of a widget controller you can name your functions
GetStrawberry()and it will still be matched. Think of the matching as something like :methodname.StartsWith("Get")Multiple Matching Methods – What happens if you have two Get methods with no parameters?
GetStrawberry()andGetOrange(). As best I can tell, the function defined first (top of the file) in your code wins …strange. This has the side effect of making some methods in your controller unreachable (at least with the default routes)….stranger.UPDATE
@WinFXGuy – This was a bit long to put in a comment, but …
Don’t jump to conclusions! I tried to answer the question you posed, but that’s only half the story. There is plenty you can do to change the default behavior.
First, WebAPI supports much of the oData spec. If you bubble an
IQueryableup to your controller, oData paramaters are automatically integrated with the query object. It takes parameters like$filter,$top, and$skip. So you in your case you can write one method and pass something like$filter=sale_date neq null.Additionally, you can apply the
[ResultLimit]attribute to prevent people asking for 15 billion records.Second you can modify the routes. The default routes aim towards a RESTful api, where you generally have 1 controller per entity. You can change the routes and make it RPC style.
If you look at my linked post I explain how I kept the default route binding, added ‘sub folders’ and also allowed additional method calls for scenarios where i needed
GetAllProducts()andGetSoldProducts().