Instructor-led Online Courses in ASP.NET Core and Angular by Bipin Joshi. Read more...
Registration open for ASP.NET Core and Angular instructor-led online courses. Courses conducted by Bipin Joshi on weekends. Click here for more details.

Multiple GET and POST methods in ASP.NET Core Web API

In ASP.NET Core MVC and Web API are parts of the same unified framework. That is why an MVC controller and a Web API controller both inherit from Controller base class. Usually a Web API controller has maximum of five actions - Get(), Get(id), Post(), Put(), and Delete(). However, if required you can have additional actions in the Web API controller. This article shows how.

Let's say you have a Web API controller named CustomerController with the following skeleton code.

[Route("api/[controller]")]
public class CustomerController : Controller
{
    [HttpGet]
    public IActionResult Get()
    {
    }


    [HttpGet("{id}")]
    public IActionResult Get(string id)
    {
    }


    [HttpPost]
    public IActionResult Post([FromBody]Customer obj)
    {
    }


    [HttpPut("{id}")]
    public IActionResult Put(string id, [FromBody] Customer obj)
    {
    }

    [HttpDelete("{id}")]
    public IActionResult Delete(string id)
    {
    }
}

Now suppose that you wish to add another GET action that returns data based on a given city and country. How can you accomplish this task?

In this specific case your new Get() action will have two parameters - city and country. This doesn't violate any overloading rules and hence you can write the following variation of Get() to get the job done.

[HttpGet("{city}/{country}")]
public IActionResult Get(string city, string country)
{
}

Notice that the [HttpGet] attribute now has two route parameters named city and country. The underlying Get() action has the corresponding method parameters. With this Get() action in place you can invoke it using the following URL :

As you can see customers from UK and London city are being returned from the Web API.

So far so good. But what if you want to have another Get() variation that has same signature to an existing Get(). In this case overloading won't work since the signatures will conflict with each other. Luckily, you can resort to attribute routing to get the job done.

Suppose you want another Get() variation that returns data based on a specific country. So the signature is going to look like this :

public IActionResult Get(string country)
{
}

This will conflict with :

public IActionResult Get(string id)
{
}

To tackle the problem you need to define a route as shown below :

 [Route("[action]/{country}")]
[HttpGet]
public IActionResult GetByCountry(string country)
{
}

Notice that the [Route] attribute now includes [action] token and {country} route parameter. The action name is GetByCountry(). To invoke this action you need to explicitly specify the action name in the URL as shown below :

Now let's see how to deal with multiple actions for POST verb.

Suppose that you wish to have an additional POST action that takes a parameter of some different type. Have a look below for an example :

[HttpPost]
public IActionResult Post([FromBody]Customer obj)
{
}

[HttpPost]
public IActionResult Post([FromBody]CustomerOrder obj)
{
}

These actions will compile successfully but will fail at runtime. That's because POST mapping will be ambiguous and the framework won't be able to decide which of the two actions is to be used.

You can again resort to routes to rectify the situation :

[HttpPost]
[Route("[action]")]
public IActionResult PostCustomerAndOrder
([FromBody]CustomerOrder obj)
{
}

Here the route includes the action name - PostCustomerAndOrder.

How will you invoke this action? A fragment of jQuery code follows :

var options= {};
options.url = "/api/customer/PostCustomerAndOrder";
options.type = "POST";
options.contentType = "application/json";
options.data = JSON.stringify(obj);
options.dataType = "json";
options.success = function (msg) { 
    console.log(msg);
};
options.error = function (msg) {
    console.log(msg);
};

$.ajax(options);

The URL includes the action name and the verb used is POST. If you wish to invoke the first Post() then the URL would be :

...
options.url = "/api/customer";
options.type = "POST";
...

Just like GET and POST verb you can deal with multiple actions for PUT and DELETE verbs.

That's it for now ! Keep coding !!


Bipin Joshi is a software consultant, trainer, author and yoga mentor having 22+ years of experience in software development. He also conducts online courses on ASP.NET MVC, ASP.NET Core and Design Patterns. He is a published author and has authored or co-authored books for Apress and Wrox press. Having embraced the Yoga way of life he also teaches Ajapa Yoga to interested individuals. To know more about him click here.

Get connected : Twitter  Facebook  Google+  LinkedIn

Posted On : 21 May 2018


Tags : ASP.NET ASP.NET Core MVC C# Visual Studio