I'm trying to implement a Controller with more than one POST method in one controller. I have the following:
public class PatientController : ApiController
{
[HttpGet]
public IEnumerable<Patient> All() { ... }
[HttpGet]
public Patient ByIndex(int index) { ... }
[HttpPost]
public HttpResponseMessage Add([FromBody]Patient patient) { ... }
}
And i have a this on my routing:
GlobalConfiguration.Configuration.Routes.MapHttpRoute(
"API_1",
"{controller}/{index}",
new { index = RouteParameter.Optional });
Everything works as expected :)
Now, i would like to add the following action:
[HttpPost, ActionName("save")]
public void Save(int not_used = -1) { ... }
Without adding anything to routing, i get the following error in to Fiddler: Multiple actions were found that match the request.
If i add this to my routing (as a second or first, doesn't matter):
GlobalConfiguration.Configuration.Routes.MapHttpRoute(
"API_2",
"{controller}/{action}/{not_used}",
new { not_used = RouteParameter.Optional },
new { action = "save|reset" }); // Action must be either save or reset
Ill get the same error in to Fiddler.
Is this even possible? Can i have more than one POST, with different (type) parameters, in one controller?
Your problem is that you have two methods: Save
and Add
, and both match your route API_1
. The fact that you have another route API_2
that could have matched if the url had been a little different doesn't matter: you have two matching methods for this route.
You've got a few options:
Save
doesn't match the default route. In particular, you've included an optional parameter in Save and that means it's OK to omit. If the parameter were non-optional, it wouldn't match the route. ServiceStack
does I can't really say what's best without understanding your exact scenario better; Though personally I'd avoid the trickiness of getting all those arguments and simultaneous routes working on multiple actions - either always be explicit about the action, or address any possible message in code (ie options 3 or 4). Complex routes in the face of optional arguments are simply a pain.
It seems that i have to modify my routing...
GlobalConfiguration.Configuration.Routes.MapHttpRoute(
name: "API_2",
routeTemplate: "{controller}/{action}/{not_used}",
defaults: new { not_used = "-1" },
constraints: new { action = "save|reset" });
GlobalConfiguration.Configuration.Routes.MapHttpRoute(
name: "API_1",
routeTemplate: "{controller}/{action}/{index}",
defaults: new { action = "EMPTY", index = RouteParameter.Optional });
...and add the ActionName-attribute to all methods:
[HttpGet, ActionName("EMPTY")]
public IEnumerable<Patient> All()
[HttpGet, ActionName("EMPTY")]
public Patient ByIndex(int index)
[HttpPost, ActionName("EMPTY")]
public HttpResponseMessage Add([FromBody]Patient patient)
[HttpPost, ActionName("save")]
public void Save(int not_used = -1)
After those modifications, i can call the save like this:
localhost:6850/Patient/save
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.