An action is a method within a controller that processes an incoming request and returns a response of a specific type.
The return type of the action determines how the framework will serialize and send the response to the client, directly affecting the format, HTTP status code, and headers of the response.
- HTTP status codes communicate the result of the operation
- Return types define the structure of the returned data
Together, they form the universal language that client applications (like frontends or mobile apps) will use to understand how to process our responses.
Returning results in an action method
The most common return type in ASP.NET for action methods is ActionResult and its derivatives.
| Return Type | Description |
|---|---|
ActionResult | Flexible base class for HTTP response |
ActionResult<T> | Combines data with HTTP status codes |
IActionResult | Interface that allows returning any type of result |
Depending on the type of result we want to send, we can use various classes and objects. Let’s look at the most common options.
It is useful when you don’t need to return a specific object, but simply communicate the result of an operation.
[HttpPost("login")]
public ActionResult Login(UserLoginDto loginDto)
{
if (!_authService.IsValidUser(loginDto))
return Unauthorized(); // 401 if credentials are invalid
var token = _authService.GenerateToken(loginDto.Username);
return Ok(new { token }); // 200 OK with JWT token
}
This approach is very common in endpoints that handle authentication, status operations, or simple responses without a fixed model.
When you need to return data along with an appropriate HTTP status, we use ActionResult<T>.
It allows returning both the object T and specific HTTP status codes:
[HttpGet("products/{id}")]
public ActionResult<ProductDto> GetProduct(int id)
{
var product = _productService.GetById(id);
if (product == null)
return NotFound(); // 404 Not Found
return product; // 200 OK + JSON of the product
}
This pattern is ideal for modern RESTful APIs that must communicate the success or failure of the operation along with the content.
IActionResult is the most flexible option and is typically used when the exact type of response can vary greatly depending on the method’s logic.
When we need to return different types of objects in the same endpoint, IActionResult is the option:
[HttpGet("report")]
public IActionResult GetReport(bool detailed)
{
if (detailed)
return Ok(_reportService.GetDetailedReport()); // 200 OK with JSON
return Content(_reportService.GetSummary(), "text/plain"); // 200 OK with plain text
}
This approach allows for more dynamic logic, albeit with less type control.
Derived Types
These methods are derived from ActionResult and encapsulate both the response content and the appropriate HTTP status code.
Using them allows you to clearly express the controller’s intent and maintain correct HTTP semantics in our APIs.
| Type | HTTP Code | When to use it |
|---|---|---|
| Ok | 200 OK | Successful GET operations |
| Created | 201 Created | Successful POST |
| Accepted | 202 Accepted | Background processing |
| NoContent | 204 No Content | Successful DELETE/PUT with no return data |
return Ok(product); // HTTP 200
return Created($"/products/{id}", product); // HTTP 201
return Accepted(); // HTTP 202
return NoContent(); // HTTP 204
| Type | HTTP Code | When to use it |
|---|---|---|
| BadRequestObject | 400 Bad Request | Failed validations or invalid data |
| Unauthorized | 401 Unauthorized | Lack of authentication |
| Forbid | 403 Forbidden | Authenticated user but without permissions |
| NotFound | 404 Not Found | GET/PUT/DELETE of a non-existent resource |
return BadRequest("Detailed message"); // HTTP 400
return Unauthorized(); // HTTP 401
return Forbid(); // HTTP 403
return NotFound(); // HTTP 404
| Type | HTTP Code | When to use it |
|---|---|---|
| StatusCode | Customizable | Special cases (e.g., 429 Too Many Requests) |
return StatusCode(429); // Custom code
return File(bytes, "image/png"); // File download
return PhysicalFile("/path", "text/csv"); // Physical file
Other return types
In addition to ActionResult and IActionResult, action methods in ASP.NET can return simple values directly.
| Return Type | Description |
|---|---|
| Direct Return | Simple return that is automatically serialized |
View() | View return in MVC applications |
In some cases, it may be necessary to return a value directly from an action method.
public int Sum(int a, int b)
{
return a + b; // Returns the value directly
}
Or even return an object directly (like ProductDto).
public IEnumerable<ProductDto> GetAllProducts()
{
return _productService.GetAll();
}
In this case, ASP.NET automatically converts the value into an HTTP response (always returns 200).
Avoid direct return types, as we lose the flexibility to represent errors or other HTTP statuses.
In MVC (Model-View-Controller) applications, which are used in web applications.
In this type of application, to return a view from an action method, we use the View() method.
public View Details(int id)
{
var product = GetProductById(id);
return View(product); // Returns the "Details" view with a product model
}
Here, the Details method receives an id parameter and searches for the corresponding product. Then, it returns a view with the product details, using the product data model.
Redirects
In some situations, an action does not need to return content directly, but rather redirect the client to another location.
ASP.NET offers methods to perform redirects, either to external URLs or to other actions within the application itself.
| Return Type | Description |
|---|---|
Redirect(string url) | Redirect to an external URL |
RedirectToAction(...) | Redirect to another action method |
In some situations, it is necessary to redirect the user to a specific URL outside the application.
This can be done using Redirect.
public ActionResult GoToGoogle()
{
return Redirect("https://www.google.com"); // Redirects the user to Google
}
In some cases, it is necessary to redirect the request to another action method, either within the same controller or to a different controller.
This can be done using the RedirectToAction instruction.
public ActionResult CreateProduct(Product product)
{
// Logic to create the product in the database
return RedirectToAction("Index"); // Redirects to the Index method
}
In this example, the CreateProduct method processes the request to create a product. After performing the operation, it redirects the user to the Index method.
These responses typically use HTTP status code 302 (Found), although they can also be customized to use other codes like 301 (Moved Permanently) or 307 (Temporary Redirect).
