Today is another ASP .Net MVC day, and as always, I encountered a challenge. Being so used with overloading methods from OOP, I asked myself what if I would do the same with the Controller’s. The sad answer is no, you can’t have two methods with the same name and SAME verb to which they will respond. The rational is simple – routing engine tries to map the request for a controller, and then will try to get the action and the verb. Since there are two methods with the same verb, you run into trouble! Let’s examine a little bit the problem and see several workarounds.
The problem
The compiler will show “Type YourController already defines a member called YourAction with the same parameter types” in the following example:
[HttpPost] public ActionResult Show() { // implementation } [HttpPost] public ActionResult ListOrders( string userName ) { // implementation }
Solutions – ASP .Net MVC 3
1. Just change for a method the request verb that will map it to a certain route – be careful to change also the calls to this action!
[HttpGet] public ActionResult ListOrders() { // implementation }
2. Another alternative would be to keep the name of the method, but decorate it with ActionName. This will map the method (valid both as name and signature for .Net, but invalid for .Net MVC framework) with another name. But be careful at the route, which will not map on the name of method, but rather on the name from the ActionName parameter:
[HttpGet] public ActionResult ListOrders() { //implementation } [HttpGet] [ActionName("ListOrdersForCustomer")] public ActionResult ListOrders( string userName ) { // implementation }
3. Create a single action method which will be responsible with both use cases, switching between them on the incoming Request type:
[HttpGet] public ActionResult ListOrders( string userName = null) { // OPTION 1 - handling by request type if (Request.HttpMethod.ToUpperInvariant() == "GET") { // do the get handling } else if (Request.HttpMethod.ToUpperInvariant() == "POST") { // do the post handling } // OPTION 2 - handling by optional parameter if ( !String.IsNullOrEmpty( userName ) ) { // do the parameter handling } else { // alternate handling } }
More about how an method becomes an action you can read in Phil Haack’s blog, one of the main contributors of the ASP .Net MVC frameworks.