Patrick Desjardins Blog
Patrick Desjardins picture from a conference

MVC cannot have two actions with the same name

Posted on: 2012-04-11

You can compile any controller to have the same method name if they have different parameter type or numbers. This is normal in .Net framework but what MVC developer must know is that you cannot have 2 actions (which are methods) with the same name even if they doesn't have the same parameter type. That mean you cannot have :

public ActionResult Edit(int id) { 
  //... 
} 

and in the same controller having:

public ActionResult Edit(MyObjectToEdit obj) {
    //... 
} 

This will fail when you will call these because the MVC framework won't know which one to call. You have two solutions to make MVC routing know which action to use. First, you can change the name. I think it's obvious that if you have different name that the routing won't have any problem to know which one to choose.

The second solution is to add the attribute POST, GET, PUT, DELETE. This will tell depending of the header. So you could have:

[HttpGet] public ActionResult Edit(int id) { 
   //... 
}

[HttpPost] public ActionResult Edit(MyObjectToEdit obj) { 
  //... 
} 

From here, you could call them by specifying in the Http Request the type of request you sent (Get or Post) and the MVC's routing system will know which one to choose.

Wait a minute

Alright, there's a catch and it's if you return from those methods Json cause you cannot return Json from a Get request by default. This is for security purpose. In fact, someone could do the attack Json HiJacking and harm you only if:

  • You return data into an array. This can be solved by returning into an object that may contain array.
  • Return sensitive information. This can be solved by using SSL.
  • Using Get with Json. This can be solved by using Post or having multiple name instead of having the same action with two types of Http call type.
  • The browser support __defineSetter__ which is where the vulnerability is executed. this one, you have no control.

So, it's not a big deal if you know what you are doing. In most case, you can allow Json to return data from Get if you handle what your action return. This mean, you should know what object you return and not returning an array directly.

To allow Json to use Get to return data, simply add as a second parameter JsonRequestBehavior.AllowGet. This will remove all possible errors.

 return Json(new { MyData = 1, MyData2= "ASD" }, JsonRequestBehavior.AllowGet);