Welcome to this lesson! In previous lessons, we focused on handling only the positive scenarios. Now, we'll venture beyond those happy paths and explore how to manage situations where users make invalid requests, such as trying to access resources that do not exist. To achieve this, we'll utilize the Results
class in ASP.NET Core. This class allows us to return meaningful HTTP status codes that indicate the success or failure of these operations, thereby making our APIs more reliable and user-friendly.
When a server responds to a request, it includes a status code that indicates the outcome. A status code is a 3-digit number, such as 200 or 404. HTTP status codes are categorized into five groups:
- 1xx (Informational): Request received, continuing process.
- 2xx (Successful): The request was successfully received, understood, and accepted.
- 3xx (Redirection): Further action needs to be taken to complete the request.
- 4xx (Client Error): The request contains bad syntax or cannot be fulfilled.
- 5xx (Server Error): The server failed to fulfill an apparently valid request.
Here are some of the most commonly used status codes that we'll be focusing on in this lesson:
Status Code | Description |
---|---|
200 | OK - The request has succeeded |
201 | Created - The request has been fulfilled, resulting in the creation of a new resource |
204 | No Content - The server successfully processed the request, but is not returning any content |
400 | Bad Request - The server could not understand the request due to invalid syntax |
401 | Unauthorized - The client must authenticate itself to get the requested response |
404 | Not Found - The server can not find the requested resource |
500 | Internal Server Error - The server has encountered a situation it doesn't know how to handle |
In ASP.NET Core, returning appropriate HTTP status codes is crucial for building robust APIs. The Results
class and the IResult
interface help streamline this process.
The Results
class provides helper methods to easily return common HTTP status codes. It simplifies your code by offering predefined responses for various scenarios, such as success, creation, no content, and not found. For example, you can use Results.NotFound()
or Results.NoContent()
.
The IResult
interface represents the result of an HTTP request. Using IResult
in your handler methods allows you to abstract the response details, making your code more modular and easier to test. It standardizes how responses are generated and returned, ensuring consistency across your application.
Let's see how to use Results
and IResult
in your Todo app. We'll start by handling a GET request to retrieve a Todo item by its ID:
C#1public IResult GetTodo(string id) => 2 TodoItem.All.TryGetValue(id, out var todo) 3 ? Results.Ok(todo) // Returns 200 OK if the item exists 4 : Results.NotFound(); // Returns 404 Not Found if it doesn't
In this example, the GetTodo
method checks if the requested item exists in the dictionary. If it does, it returns Results.Ok(todo)
, which corresponds to an HTTP 200 OK status. If the item doesn't exist, it returns Results.NotFound()
, which corresponds to an HTTP 404 Not Found status.
Next, let's handle a DELETE request to remove a Todo item by its ID:
C#1public IResult DeleteTodo(string id) => 2 TodoItem.All.TryRemove(id, out _) 3 ? Results.NoContent() // Returns 204 No Content if the item is successfully deleted 4 : Results.NotFound(); // Returns 404 Not Found if it doesn't exist
In this example, the DeleteTodo
method attempts to remove the item with the specified ID from the dictionary. If the removal is successful, it returns Results.NoContent()
, indicating that the request was successful but there is no content to return (HTTP 204 No Content). If the item is not found, it returns Results.NotFound()
, indicating that the requested resource could not be found (HTTP 404 Not Found).
Here are some of the most frequently used methods in the Results
class:
Results.Ok(object value)
– Returns status code 200 (OK) with the specified value.Results.Created(string location, object value)
– Returns status code 201 (Created) with a location header pointing to the newly created resource.Results.NoContent()
– Returns status code 204 (No Content).Results.BadRequest(object error)
– Returns status code 400 (Bad Request) with the specified error message or object.Results.Unauthorized()
– Returns status code 401 (Unauthorized).Results.NotFound()
– Returns status code 404 (Not Found).Results.StatusCode(int statusCode)
– Returns a custom status code.
In this lesson, we explored how to make our APIs more reliable by handling scenarios where users try to access non-existent resources. We also learned to return meaningful HTTP status codes using the Results
class. This helps in effectively communicating the outcome of requests to clients. Through this, we're able to build robust, user-friendly APIs.