Controller Action Return Types in ASP.NET Core Web API

Controller Action Return Types in ASP.NET Core Web API

In this article, I am going to discuss the different Controller Action Method Return Types in ASP.NET Core Web API Application with Examples. Please read our previous article, where we discussed Routing in ASP.NET Core Web API. At the end of this article, you will understand what are the different ways to return data from the ASP.NET Core Controller action method.

Controller Action Return Types in ASP.NET Core Web API

In ASP.NET Core Web API, in three different ways, we can return data from the controller action method. They are as follows:

  1. Specific type
  2. IActionResult
  3. ActionResult<T>

Let us discuss each of them in detail. Before understanding this, let us first create a new ASP.NET Core Web API project with the name ReturnTypeAndStatusCodes.

Adding Employee Model:

Once you created the Project, then add a folder with the name Models to the project root directory. Then add a class file with the name Employee.cs with the Models folder. Then open the Employee.cs class and copy-paste the following code in it. This is a very simple Employee class that contains Id, Name, Gender, City, Age, and Department properties.

namespace ReturnTypeAndStatusCodes.Models
{
    public class Employee
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Gender { get; set; }
        public string City { get; set; }
        public int Age { get; set; }
        public string Department { get; set; }
    }
}
Adding Employee Controller:

Then add an empty ASP.NET Core Web API Controller with the name EmployeeController within the Controllers folder. Once you created the controller, it should be created with the following code.

using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
namespace ReturnTypeAndStatusCodes.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class EmployeeController : ControllerBase
    {
    }
}

Specific Type as the Return type in ASP.NET Core Web API

We can return any type of primitive data like string, integer, Boolean, etc., or complex data like Employee, Product, etc, directly from the controller action method.

Returning String from ASP.NET Core Web API Controller Action Method:

Please add the following action method within the Employee Controller. The following GetName Method simply returning a string.

[Route("Name")]
public string GetName()
{
    return "Return from GetName";
}

Now save the changes, run the application and navigate to api/employee/name and you should get the following response.

Returning String from ASP.NET Core Web API Controller Action Method

In this case, you can return any primitive data from the ASP.NET Core Web API Controller action method.

Returning Complex Type in ASP.NET Core Web API:

Now let us see how to return complex data from the controller action method. As we have created the Employee model, let us return an employee object from the controller action method. So, add the following GetEmployeeDetails action method within the Employee Controller. Also, add the namespace to which the Employee model belongs to.

[Route("Details")]
public Employee GetEmployeeDetails()
{
    return new Employee()
    {
        Id = 1001,
        Name = "Anurag",
        Age = 28,
        City = "Mumbai",
        Gender = "Male",
        Department = "IT"
    };
}

With the above action method in place, now run the application and navigate to api/employee/details and you should get the following response. Here, you are getting the response in JSON format which will return the employee data in key-value pair.

Returning List<T> from ASP.NET Core Web API Action Method

Now let us see how to return a complex type of collection data from the controller action method. Let us return the List of employees from the controller action method. So, add the following GetAllEmployee action method within the Employee Controller.

[Route("All")]
public List<Employee> GetAllEmployee()
{
    return new List<Employee>()
            {
                new Employee(){ Id = 1001, Name = "Anurag", Age = 28, City = "Mumbai", Gender = "Male", Department = "IT" },
                new Employee(){ Id = 1002, Name = "Pranaya", Age = 28, City = "Delhi", Gender = "Male", Department = "IT" },
                new Employee(){ Id = 1003, Name = "Priyanka", Age = 27, City = "BBSR", Gender = "Female", Department = "HR"},
            };
}

With the above changes in place, run the application and navigate to api/employee/all and you should get the following response. Here, you are getting the list of employees as an array of JSON.

Returning List<T> from ASP.NET Core Web API Action Method

Returning IEnumerable<T> from ASP.NET Core Web API Controller Actions

Instead of using List<Employee> as return type, you can also use IEnumerable<Employee>. Please modify the GetAllEmployee action method as shown below.

[Route("All")]
public IEnumerable<Employee> GetAllEmployee()
{
    return new List<Employee>()
            {
                new Employee(){ Id = 1001, Name = "Anurag", Age = 28, City = "Mumbai", Gender = "Male", Department = "IT" },
                new Employee(){ Id = 1002, Name = "Pranaya", Age = 28, City = "Delhi", Gender = "Male", Department = "IT" },
                new Employee(){ Id = 1003, Name = "Priyanka", Age = 27, City = "BBSR", Gender = "Female", Department = "HR"},
            };
}

Now run the application and navigate to api/employee/all and you should get the same response as the previous example.

Returning IAsyncEnumerable<T> From ASP.NET Core Web API Action Methods:

In ASP.NET Core 3.0 and later, you can return IAsyncEnumerable<T> from an action method that provides the following benefits:

  1. It no longer results in synchronous iteration.
  2. Becomes as efficient as returning IEnumerable<T>.

So, ASP.NET Core 3.0 and later buffers the result of the action method before providing it to the serializer. So, to understand this concept, please add the following GetAllEmployeeAsync action method within the Employee Controller.

[Route("All/Async")]
public async IAsyncEnumerable<Employee> GetAllEmployeeAsync()
{
    var listEmployees = new List<Employee>()
            {
                new Employee(){ Id = 1001, Name = "Anurag", Age = 28, City = "Mumbai", Gender = "Male", Department = "IT" },
                new Employee(){ Id = 1002, Name = "Pranaya", Age = 28, City = "Delhi", Gender = "Male", Department = "IT" },
                new Employee(){ Id = 1003, Name = "Priyanka", Age = 27, City = "BBSR", Gender = "Female", Department = "HR"},
            };

    foreach (var item in listEmployees)
    {
        yield return item;
    }
}

Now save the changes and run the application and navigate to api/employee/all/async and you should get the following JSON array as a response.

Returning IAsyncEnumerable<T> From ASP.NET Core Web API Action Methods

So, the Specific return type that we can return from an ASP.NET Core Web API Controller action method are as follows:

  1. Any primitive data types from action methods such as int, string, bool, etc.
  2. Any complex data object such as Employee, Student, Product, etc.
  3. Collection of objects (like List<T> etc)
  4. IEnumerable<T>
  5. IAsyncEnumerable<T>, etc.
Benefits of using Specific Return Type in ASP.NET Core Web API:

While using the swagger or similar type of application, there is no need to define ProducesResponseType because we have defined the return type explicitly.

The drawback of using Specific Return Type in ASP.NET Core Web API:

You cannot return multiple types of data, let’s say NotFound, OK, Redirect, etc. which are very common in ASP.NET Core Web API to indicate the status of the request.

IActionResult Return Type in ASP.NET Core Web API:

The IActionResult return type is appropriate when multiple ActionResult return types are possible in an action. The ActionResult types represent various HTTP status codes.

The IActionResult is an interface and it is used to return multiple types of data. For example, if you want to return NotFound, OK, Redirect, etc. data from your action method then you need to use IActionResult as the return type from your action method. The following is the signature of the IActionResult interface.

IActionResult Return Type in ASP.NET Core Web API

The IActionResult interface defines a contract that represents the result of an action method. This interface has the ExecuteResultAsync method. The ExecuteResultAsync method Executes the result operation of the action method asynchronously. This method is called MVC to process the result of an action method and returns a task that represents the asynchronous execute operation. It accepts the context parameter in which the result is going to be executed. The context information includes information about the action that was executed and request information.

Example to understand IActionResult in ASP.NET Core Web API:

We want to return a list of employees from our action method. If the number of employees is greater than 0, then we need to return the status OK with the list of employees else we need to return the status Not Found. We can achieve this very easily by using the IActionResult result type. So, modify the Employee Controller as shown below. Here, we have created one action method i.e. GetAllEmployees with the return type as IActionResult.

using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
using ReturnTypeAndStatusCodes.Models;

namespace ReturnTypeAndStatusCodes.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class EmployeeController : ControllerBase
    {
        [Route("All")]
        public IActionResult GetAllEmployee()
        {
            var listEmployees = new List<Employee>()
                    {
                        new Employee(){ Id = 1001, Name = "Anurag", Age = 28, City = "Mumbai", Gender = "Male", Department = "IT" },
                        new Employee(){ Id = 1002, Name = "Pranaya", Age = 28, City = "Delhi", Gender = "Male", Department = "IT" },
                        new Employee(){ Id = 1003, Name = "Priyanka", Age = 27, City = "BBSR", Gender = "Female", Department = "HR"},
                    };

            if(listEmployees.Count > 0)
            {
                return Ok(listEmployees);
            }
            else
            {
                return NotFound();
            }
        }
    }
}

First, run the application and find the port number on which your application is running. Now in order to check the returned data with status, we are going to use the Postman client tool. So, open postman and then make a GET to Request as shown in the below image.

Example to understand IActionResult in ASP.NET Core Web API

As you can see in the above image, first select the HTTP verb as GET and then provide the URL and finally click on the Send button which will make a GET request to the URL you specified. Once you hit the send button, you will get the following response. Notice along with the employee data in JSON format, here, you are also getting status code as 200 OK as shown in the below image.

IActionResult Return Type in ASP.NET Core Web API

Returning Not Found Data using IActionResult in ASP.NET Core:

Now add the following GetEmployeeDetail Action method within the Employee Controller. It accepts the Employee Id as an input parameter and then returns that employee data. If the employee id is existing then it will return the employee data else it will return Not Found data.

[Route("{Id}")]
public IActionResult GetEmployeeDetails(int Id)
{
    var listEmployees = new List<Employee>()
                    {
                        new Employee(){ Id = 1001, Name = "Anurag", Age = 28, City = "Mumbai", Gender = "Male", Department = "IT" },
                        new Employee(){ Id = 1002, Name = "Pranaya", Age = 28, City = "Delhi", Gender = "Male", Department = "IT" },
                        new Employee(){ Id = 1003, Name = "Priyanka", Age = 27, City = "BBSR", Gender = "Female", Department = "HR"},
                    };

    var employee = listEmployees.FirstOrDefault(emp => emp.Id == Id);

    if (employee != null)
    {
        return Ok(employee);
    }
    else
    {
        return NotFound();
    }
} 

Save the changes and run the application and issue the following request from the postman. As you can see, here, we passing the employee id as 105 which does not exist.

Returning IActionResult Type in ASP.NET Core Web API Action Method

As you can see in the above image, we select the HTTP verb as GET and then provide the URL and finally click on the Send button which will make a GET request to the URL you specified. Once you hit the send button, you will get the following response. Notice, now we are getting 404 Not Found response as the employee id which we are sending does not exist.

Returning Not Found Data using IActionResult in ASP.NET Core

Now if you issue a request with an existing employee Id then you will get a 200 OK status code with the employee data in JSON format as shown in the below image.

Returning OK Data using IActionResult in ASP.NET Core

So, as you can see in the above example, for the same action method GetEmployeeDetails we returned two different types of data. The IActionResult is an Interface and allows us to return multiple types. You can return the data using some built-in methods are as follows.

  1. OK()
  2. NotFound()
  3. Content()
  4. File()
  5. Redirect, Etc.
Benefits of using IActionResult type in ASP.NET Core Web API

It allows us to return multiple types of data along with the status code, this is very important for RESTful APIs

The drawback of using IActionResult type in ASP.NET Core Web API

As it returns multiple types of data, the swagger would not be able to identify the output, so we need to use the ProducesResponseType explicitly as shown below.

[Route("{Id}")]
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(Employee))]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public IActionResult GetEmployeeDetails(int Id)
{
    var listEmployees = new List<Employee>()
                    {
                        new Employee(){ Id = 1001, Name = "Anurag", Age = 28, City = "Mumbai", Gender = "Male", Department = "IT" },
                        new Employee(){ Id = 1002, Name = "Pranaya", Age = 28, City = "Delhi", Gender = "Male", Department = "IT" },
                        new Employee(){ Id = 1003, Name = "Priyanka", Age = 27, City = "BBSR", Gender = "Female", Department = "HR"},
                    };

    var employee = listEmployees.FirstOrDefault(emp => emp.Id == Id);

    if (employee != null)
    {
        return Ok(employee);
    }
    else
    {
        return NotFound();
    }
}

ActionResult<T> Return Type in ASP.NET Core Web API:

It is the combination of ActionResult and Specific type. The ASP.NET Core 2.1 introduced the ActionResult<T> return type for the Web API controller action methods. It enables us to return a type deriving either from ActionResult or return a specific type.

Let us understand this with an example. Please modify the Employee Controller class as shown below. The GetEmployeeDetails method takes one parameter and if the parameter value is 0, then it returns NotFound else it returns the employee object.

using Microsoft.AspNetCore.Mvc;
using ReturnTypeAndStatusCodes.Models;

namespace ReturnTypeAndStatusCodes.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class EmployeeController : ControllerBase
    {
        [Route("{Id}")]
        public ActionResult<Employee> GetEmployeeDetails(int Id)
        {
            if (Id == 0)
            {
                return NotFound();
            }
            else
            {
                return new Employee() { Id = 1001, Name = "Anurag", Age = 28, City = "Mumbai", Gender = "Male", Department = "IT" };
            }
        }
    }
}
Advantages of ActionResult<T> over ActionResult in ASP.NET Core Web API:

ActionResult<T> offers the following benefits over the IActionResult type:

  1. The [ProducesResponseType] attribute’s Type property can be excluded. For example, [ProducesResponseType(200, Type = typeof(Employee))] is simplified to [ProducesResponseType(200)]. The action’s expected return type is instead inferred from the T in ActionResult<T>.
  2. Implicit cast operators support the conversion of both T and ActionResult to ActionResult<T>. T converts to ObjectResult, which means return new ObjectResult(T); is simplified to return T.

In the next and few upcoming articles, we are going to discuss the most useful Status Codes Methods in ASP.NET Core Web API Application. Here, in this article, I try to explain Controller Action Method Return Types in ASP.NET Core Web API Application with Examples. I hope you enjoy how to return different return types in the ASP.NET Core Web API Controller action methods article.

Leave a Reply

Your email address will not be published. Required fields are marked *