Three Ways To Return The Data From Controller Action Method In ASP.NET Core Web API

There are 3 ways to return the data from action method in Asp.Net Core Web API.
  1. Specific type
  2. IActionResult
  3. ActionResult<T>
Let's learn all of them one by one.
 

Return the Specific Type from Asp.Net Core Web API action method

 
Specifc type is used to return the Primitive (string, boolean, int, etc) or Complex data (Custom object type) from an action method.
 
Return the string type from action method in asp.net core web API, 
  1. [Route("website/name")]    
  2. public string GetWebsiteName()    
  3. {    
  4.     return "Website ABC";    
  5. }  
Return a complex data from action method in asp.net core web API, 
  1. [Route("emplpyees/{id}")]  
  2. public Employee GetEmployeeById(int id)  
  3. {  
  4.     var employee = new Employee() { Id = 1, Name = "Nitish" }; // Get the data from db  
  5.     return employee;  
  6. }  
 Specific type allows us to return,
  • Any primitive data types from action method
  • Any complex data object
  • Collection of objects (like List<T> etc)
  • IEnumerable<T>
  • IAsyncEnumerable<T>
  • etc.
Benifits of using Specific type
 
While using the swagger or similar application then there is no need to define ProducesResponseType because we have defined the return type explictly.
 
Drawback of using Specific type
 
You cannot return multiple types of data, let's say NotFound, OK, Redirect etc.
 

Return IActionResult type from Asp.Net Core Web API action method

 
This IActionResult is an Interface and it is very powerful because it allows us to return multiple types. We can return the data using some buit-in methods.
like,
  • OK()
  • NotFound()
  • Content()
  • File()
  • Etc.
Let's return the employee data using IActionResult type 
  1. [Route("emplpyees/{id}")]  
  2. public IActionResult GetEmployeeById(int id)  
  3. {  
  4.     if (id == 0)  
  5.     {  
  6.         return NotFound();  
  7.     }  
  8.     var employee = new Employee() { Id = 1, Name = "Nitish" }; // Get the data from db  
  9.     return Ok(employee);  
  10. }  
In the above code, you can notice that we are returning two different types.
 
Benifits of using IActionResult type
 
It allows us to return multiple types of data along with the status code, this is very important for RESTful APIs
 
Drawback of using IActionResult type
 
Because of its ability to return multiple types of data the swagger would not be able to identify the output so we need to use the  ProducesResponseType explictly.
  1. [Route("emplpyees/{id}")]  
  2. [ProducesResponseType(StatusCodes.Status201Created, Type = typeof(Employee))]  
  3. [ProducesResponseType(StatusCodes.Status400BadRequest, Type = typeof(Employee))]  
  4. public IActionResult GetEmployeeById(int id)  
  5. {  
  6.     if (id == 0)  
  7.     {  
  8.         return NotFound();  
  9.     }  
  10.     var employee = new Employee() { Id = 1, Name = "Nitish" }; // Get the data from db  
  11.     return Ok(employee);  
  12. }

Return ActionResult<T> type from Asp.Net Core Web API action method

 
ActionResult<T> was introduced in Asp.Net Core 2.1 and it can resturn both specific type as well as the built-in (Asp.Net Core) methods.
 
Let's return the primitive data type and not found data using ActionResult<T> type,
  1. [Route("website/{websiteId}/name")]  
  2. public ActionResult<string> GetWebsiteName(int websiteId)  
  3. {  
  4.     if (websiteId == 0)  
  5.     {  
  6.         return NotFound();  
  7.     }  
  8.     return "Website ABC";  
  9. }  
We can also return any complex data object using ActionResult<T> type
  1. [Route("emplpyees/{id}")]  
  2. public ActionResult<Employee> GetEmployeeById(int id)  
  3. {  
  4.     if (id == 0)  
  5.     {  
  6.         return NotFound();  
  7.     }  
  8.     var employee = new Employee() { Id = 1, Name = "Nitish" }; // Get the data from db  
  9.     return employee;  
  10. }  
Benifits of using ActionResult<T> type
  • It allows to return multiple types of data along with the status code
  • Since we are definng the return type explictly, there is no need to use Type in ProducesResponseType attribute.
  1. [Route("emplpyees/{id}")]  
  2. [ProducesResponseType(StatusCodes.Status201Created)]  
  3. [ProducesResponseType(StatusCodes.Status400BadRequest)]  
  4. public ActionResult<Employee> GetEmployeeById(int id)  
  5. {  
  6.     if (id == 0)  
  7.     {  
  8.         return NotFound();  
  9.     }  
  10.     var employee = new Employee() { Id = 1, Name = "Nitish" }; // Get the data from db  
  11.     return employee;  
  12. }  
Drawback of using ActionResult<T> type
 
Still the use of ProducesResponseType is required for status codes.