In this article, we will learn about the different ways to return a 500 status code with ASP.NET Core Web API controller actions.

To download the source code for this article, you can visit our GitHub repository.

Let’s start!

Returning 500 Status Code

Let’s utilize the .NET Web API project for our implementation. 

Within the code, we intend to replicate the execution process of the exception segment. Moreover, we aim to implement this methodology across all methods. This objective can be accomplished by establishing a private method dedicated to raising exceptions. For a more comprehensive understanding of the implementation, feel free to explore the provided code snippets.

Returning Status Code as a Number

One of the most frequently used approaches for returning the HTTP status code from the controller method is to return it as a number:

Don't like the ads? Take a second to support Code Maze on Patreon and get the ad free reading experience!
Become a patron at Patreon!
[HttpGet]
[Route("GetUsersFirstMethod")]
public IActionResult GetUsersFirstMethod()
{
    try
    {
        SimulateException();

        return Ok(_userService.GetAllUsers());
    }
    catch (Exception ex)
    {
        return StatusCode(500, ex.Message);
    }
}

The StatusCodeResult in Web API enables us to return an HTTP status code without a specific response body. This approach involves using the StatusCode() method from the ControllerBase class to quickly return an HTTP 500 status code. Additionally, for a 500 status code, the default status message is Internal Server Error. Furthermore, this method offers the flexibility to include a message as a secondary parameter, allowing for more comprehensive and informative responses to the user.

Here is the response we got from Postman:

Simulated exception

In the upcoming example, let’s follow the previous approach involving the StatusCode class, but with a slight variation.

Returning Status Code as an Enumeration

The second most common option for returning an HTTP status code to the client is by using enumeration:

[HttpGet]
[Route("GetUsersSecondMethod")]
public IActionResult GetUsersSecondMethod()
{
    try
    {
        SimulateException();

        return Ok(_userService.GetAllUsers());
    }
    catch (Exception ex)
    {
        return StatusCode(StatusCodes.Status500InternalServerError);
    }
}

In the context of returning HTTP status codes, using a numerical value directly or an enumeration isn’t fundamentally different. Both approaches serve the same purpose of indicating the desired HTTP status code in the response.

By utilizing an enumeration, we make use of a predefined set of named constants that represent HTTP status codes. Enumerations offer a more transparent and self-explanatory method to indicate the status code. Usually, frameworks or libraries providing HTTP-related functionalities contain these enumerations.

The choice between using a numerical value or an enumeration primarily depends on personal preference and code readability.

On one hand, using an enumeration can enhance code readability, providing self-documenting and self-explanatory status code representations. On the other hand, opting for a numerical value directly can offer a more succinct approach in specific instances.

Here is the response message after receiving the response:

{
    "type": "https://tools.ietf.org/html/rfc7231#section-6.6.1",
    "title": "An error occurred while processing your request.",
    "status": 500,
    "traceId": "00-63e3efa6a8de0305d77fb2662e8a13a3-7fcedf6c67cdcd0c-00"
}

Returning ContentResult Object

Moreover, by utilizing the ContentResult object, we have the capability to furnish additional information:

[HttpGet]
[Route("GetUsersThirdMethod")]
public IActionResult GetUsersThirdMethod()
{
    try
    {
        SimulateException();

        return Ok(_userService.GetAllUsers());
    }
    catch (Exception ex)
    {
        return new ContentResult
        {
            StatusCode = (int)HttpStatusCode.InternalServerError,
            Content = "An error occurred while processing the request.",
            ContentType = "text/plain"
        };
    }
}

Instead of directly using the StatusCode() method, we opt to create a new instance of the ContentResult class, which allows us to customize its properties. This class comprises three essential properties: Content, ContentType, and StatusCode, along with a method that returns an ContentResult object.

The Content property denotes the actual content that will be included in the response body. We have the freedom to set this property to various data types, such as strings, JSON, or XML. Meanwhile, the ContentType specifies the MIME type of the content.

By configuring these properties, we gain the ability to customize multiple aspects of the response generated by the ContentResult. Such flexibility allows us to tailor the HTTP response according to our specific requirements, enhancing the overall functionality of our application.

The response message from Postman is:

An error occurred while processing the request.

Now, let’s move on to the next method.

Using ProblemDetails Object

In the following example, let’s see the possibility of returning the HTTP status code with the help of the ProblemDetails object:

[HttpGet]
[Route("GetUsersFourthMethod")]
public IActionResult GetUsersFourthMethod()
{
    try
    {
        SimulateException();

        return Ok(_userService.GetAllUsers());
    }
    catch (Exception ex)
    {
        var problemDetails = new ProblemDetails
        {
            Status = (int)HttpStatusCode.InternalServerError,
            Title = "Internal Server Error",
            Detail = "An error occurred while processing the request."
        };

        return new ObjectResult(problemDetails)
        {
            StatusCode = (int)HttpStatusCode.InternalServerError
        };
    }
}

The ProblemDetails class is a part of ASP.NET Core, and it serves as the standard format for returning error details in an HTTP response. It encompasses properties such as Status, Title, and Detail, which provides crucial error information. Notably, the Status property is set to 500 to signify an internal server error. Additionally, the Title property offers a concise error description, while the Detail property provides supplementary information.

To transmit the ProblemDetails object as the response, we encapsulate it within an ObjectResult object, conveying the status code that the client will receive upon requesting this API method.

Let’s look at the output response message that the client receives after sending the request:

{
    "title": "Internal Server Error",
    "status": 500,
    "detail": "An error occurred while processing the request."
}

These methods showcase standard practices for returning status code 500 and related status codes to the client. They predominantly follow a consistent pattern, using try-catch and finally blocks to handle potential exceptions effectively. We can consolidate these aspects for a more streamlined approach by implementing middleware and establishing global error handling.

Conclusion

In this article, we delved into the various types of 500 status code returns that can potentially occur within ASP.NET Core Web API Controller actions. Moreover, conducted a thorough examination of several common instances of status code returns and elaborated on the recommended approach.

Additionally, we elaborated on the recommended approach for effectively managing these error scenarios. Besides, we provided a comprehensive understanding of the best practices and strategies to handle these situations successfully.

Liked it? Take a second to support Code Maze on Patreon and get the ad free reading experience!
Become a patron at Patreon!