SoFunction
Updated on 2025-03-04

Explain how to return data in three ways in the Core Web API

There are three ways to return data and HTTP status codes in Core. The easiest way is to directly return the specified type instance, as shown in the following code:

  [ApiController]
  [Route("[controller]")]
  public class WeatherForecastController : ControllerBase
  {
    [HttpGet]
    public IEnumerable<WeatherForecast> Get()
    {
      var rng = new Random();
      return (1, 5).Select(index => new WeatherForecast
      {
        Date = (index),
        TemperatureC = (-20, 55),
        Summary = Summaries[()]
      })
      .ToArray();
    }
  }

In addition to this, you can also return an IActionResult instance and an ActionResult <T> instance.

Although returning the specified type is the simplest and crudest, it can only return data and cannot come with an http status code. The IActionResult instance can bring data + Http status code to the front end. Finally, ActionResult<T> It encapsulates the first two and can realize free switching between the two modes, 🐂.

Next, let’s discuss how to use these three ways in the Core Web API.

Create Controller and Model classes

Create a new Author class in the project's Models folder, with the following code:

  public class Author
  {
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
  }

With this Author class, next create a DefaultController class.

using ;
using ;

namespace 
{
  [Route("api/[controller]")]
  [ApiController]
  public class DefaultController : ControllerBase
  {
    private readonly List<Author> authors = new List<Author>();
    public DefaultController()
    {
      (new Author()
      {
        Id = 1,
        FirstName = "Joydip",
        LastName = "Kanjilal"
      });
      (new Author()
      {
        Id = 2,
        FirstName = "Steve",
        LastName = "Smith"
      });
    }

    [HttpGet]
    public IEnumerable<Author> Get()
    {
      return authors;
    }

    [HttpGet("{id}", Name = "Get")]
    public Author Get(int id)
    {
      return (x =>  == id);
    }
  }
}

Returns the specified type in Action

The easiest way is to directly return a simple type or complex type in Action. In fact, in the above code list, you can see that the Get method returns an authors collection. You can see clearly that this method defines IEnumerable<Author>.

[HttpGet]
public IEnumerable<Author> Get()
{
  return authors;
}

Starting from Core 3.0, you can not only define the synchronous form of IEnumerable<Author> method, but also the asynchronous form of IAsyncEnumerable<T> method. The difference between the latter is that it is a collection of asynchronous patterns. The advantage is that it does not block the current calling thread. I will share more knowledge about IAsyncEnumerable<T> with you in the following article.

The following code shows how to use asynchronous collections to modify the Get method.

[HttpGet]
public async IAsyncEnumerable<Author> Get()
{
  var authors = await GetAuthors();
  await foreach (var author in authors)
  {
    yield return author;
  }
}

Returns an IActionResult instance in Action

If you want to return the dual requirement of data + httpcode, then IActionResult is what you are looking for. The following code snippet shows how to implement it.

[HttpGet]
public IActionResult Get()
{
 if (authors == null)
   return NotFound("No records");

 return Ok(authors);
}

The above code has two methods: Ok and NotFound, which correspond to OKResult, NotFoundResult, and Http Code corresponds to 200 and 404. Of course, there are other ones such as CreatedResult, NoContentResult, BadRequestResult, UnauthorizedResult, and UnsupportedMediaTypeResult, which are all subclasses of IActionResult.

Returns an ActionResult<T> instance in Action

ActionResult<T> was introduced in Core 2.1. Its function is to wrap the previous pattern. How do you understand it? That is, you can return IActionResult or return the specified type, which can be seen from the two constructors under the ActionResult<TValue> class.

public sealed class ActionResult<TValue> : IConvertToActionResult
{
  public ActionResult Result {get;}

  public TValue Value {get;}

  public ActionResult(TValue value)
  {
    if (typeof(IActionResult).IsAssignableFrom(typeof(TValue)))
    {
      throw new ArgumentException((typeof(TValue), "ActionResult<T>"));
    }
    Value = value;
  }

  public ActionResult(ActionResult result)
  {
    if (typeof(IActionResult).IsAssignableFrom(typeof(TValue)))
    {
      throw new ArgumentException((typeof(TValue), "ActionResult<T>"));
    }
    Result = (result ?? throw new ArgumentNullException("result"));
  }
}

With this foundation, let’s take a look at how to take these two types in the Action method.

[HttpGet]
public ActionResult<IEnumerable<Author>> Get()
{
 if (authors == null)
    return NotFound("No records");
  return authors;
}

Compared with the Get method before the article, Is it a very good simplification to return authors directly without using OK(authors) to wrap it? Next, asynchronously the Get method, first consider the asynchronous method that returns the authors collection below.

private async Task<List<Author>> GetAuthors()
{
  await (100).ConfigureAwait(false);
  return authors;
}

It is worth noting that the asynchronous method must have at least one await statement. If you do not do this, the compiler will prompt a warning error to tell you that this method will be executed synchronously. In order to avoid this embarrassment, I made an await on it.

The following is the updated Get method. Note that I used await to call the asynchronous method I just created. The code reference is as follows.

[HttpGet]
public async Task<ActionResult<IEnumerable<Author>>> Get()
{
  var data = await GetAuthors();
  if (data == null)
    return NotFound("No record");
  return data;
}

If you have some customization requirements, you can implement a custom ActionResult class. The method is to implement the ExecuteResultAsync method in IActionResult.

Translation link:/article/3520770/

This is the end of this article about how to return data in three ways in the Core Web API. For more related Core Web API to return data, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!