In this article, we are going to see how to add multiple POST actions to our Web API controller. For the demonstration, we are going to use the .Net 6 Web API project.
Let’s start.
The Issue With Multiple POST Actions in Web API
In this section, we are going to use a controller with two POST actions, and explain the routing issue and what error we are going to get once we send the POST request to one of these actions:
[ApiController] [Route("[controller]")] public class StudentsController : ControllerBase { readonly List<Student> students = new() { new Student(1, "Pedro Whitted"), new Student(2, "Lester Harvin"), new Student(3, "Phyllis Wiggins") }; readonly List<StudentGrade> grades = new() { new StudentGrade(1, 3.2), new StudentGrade(2, 2.5), new StudentGrade(3, 3.7) }; [HttpPost] public ActionResult PostStudent(Student student) { students.Add(student); return StatusCode(201); } [HttpPost] public ActionResult PostGrade(StudentGrade grade) { grades.Add(grade); return StatusCode(201); } }
In the PostStudent
action, we add a new student to our local collection. Also, in the second action, we add the student’s grades to the collection.
At this point, if we send a POST HTTP request to the controller:
https://localhost:7042/Students
We are going to get a response with a 500 Internal Server Error
status code.
Also, we can see the error message:
Microsoft.AspNetCore.Routing.Matching.AmbiguousMatchException: The request matched multiple endpoints.
It means our application couldn’t determine which POST action to execute in our controller!
Now if we try to edit our URI and add the action name to it:
https://localhost:7042/Students/PostStudent
We will notice that the server responds with 404 Not Found
status code.
Resolving Multiple Post Actions Issue
We can solve this issue with one of two options: using RoutAttribute
or by using HttpPostAttribute
.
RouteAttribute
By default, we can see the Route
attribute above the controller with a string "[controller]"
as a parameter:
[Route("[controller]")] public class StudentsController : ControllerBase
This means the URI for this controller is:
http[s]://[domain]/[controller]
But we can use this Route
attribute above the action method as well:
[Route("[action]")] [HttpPost] public ActionResult PostStudent(Student student)
By using the "[action]"
string as a parameter here, we state that the URI must contain this action’s name in addition to the controller’s name:
http[s]://[domain]/[controller]/[action]
Now, let’s try to call our API with the action’s name in the URI:
https://localhost:7042/Students/PostStudent
After we do that, we notice the 201, created
response. We don’t have the error anymore.
If we want, we can assign a different action name in the URI. For example, instead of using the PostStudent
action name, we can use the AddStudent
:
[Route("AddStudent")] [HttpPost] public ActionResult PostStudent(Student student)
After this change, we have a different URI:
https://localhost:7042/Students/AddStudent
HttpPostAttribute
We can simplify our code by removing the Route
attribute, and use the HttpPost
attribute solely. It has an override that takes the same string parameter as the Route
attribute:
[HttpPost("[action]")] public ActionResult PostStudent(Student student)
Now, for the URI, we have to provide the name of the action:
https://localhost:7042/Students/PostStudent
And if we need to change the name of the action in the URI, we can simply use a different string as with the [Route]
example:
[HttpPost("AddStudent")] public ActionResult PostStudent(Student student)
Now the AddStudent
string will be part of the URI:
https://localhost:7042/Students/AddStudent
Conclusion
In this article, we’ve learned how to add multiple POST actions in a single controller, and how to call each of them without forcing an error.
Thank you! This helped me a lot!
Thanks a lot for the comment and for reading the article. It’s awesome that the article helped you.
Really helpful, I thought this routing things didn’t care because the compiler get all from the method name, but you open my mind hahaha. Good job, my friend
I’m glad the article could help you. Thank you for reading it.
I really like these articles. They are helpful and informative.
Thanks a lot Keith.