joydip_kanjilal
Contributor

How to handle null values in ASP.NET Core MVC

how-to
Sep 02, 20195 mins
C#Microsoft .NETSoftware Development

Learn to change the default behavior and return HTTP 404 when action methods in ASP.NET Core return null values.

question marks
Credit: Murat Göçmen / Getty Images

ASP.NET Core MVC is the .NET Core counterpart of the ASP.NET MVC framework. You can take advantage of ASP.NET Core MVC to build cross-platform, scalable, high-performance web applications and APIs using the Model-View-Controller design pattern.

We always want to handle errors elegantly in our web applications. When it comes to empty responses to requests, or returning null values from the action methods, the ASP.NET Core MVC framework returns HTTP Status Code 204, i.e., the “No Content” response. In this article we’ll examine how we can change this default behavior when the action methods return null values.

To work with the code examples illustrates in this article, you should have Visual Studio 2019 installed in your system. If you don’t already have a copy, you can download Visual Studio 2019 here

Create an ASP.NET Core MVC project in Visual Studio

First off, let’s create an ASP.NET Core project in Visual Studio 2019. Assuming Visual Studio 2019 is installed in your system, follow the steps outlined below to create a new ASP.NET Core project in Visual Studio.

  1. Launch the Visual Studio IDE.
  2. Click on “Create new project.”
  3. In the “Create new project” window, select “ASP.NET Core Web Application” from the list of templates displayed.
  4. Click Next.
  5. In the “Configure your new project” window, specify the name and location for the new project.
  6. Click Create.
  7. In the “Create a New ASP.NET Core Web Application” window shown next, select .NET Core as the runtime and ASP.NET Core 2.2 (or later) from the drop-down list at the top.
  8. Select “Web Application (Model-View-Controller)” as the project template to create a new ASP.NET Core application. 
  9. Ensure that the check boxes “Enable Docker Support” and “Configure for HTTPS” are unchecked as we won’t be using those features here.
  10. Ensure that Authentication is set to “No Authentication” as we won’t be using authentication either.
  11. Click Create. 

Following these steps should create a new ASP.NET Core project in Visual Studio. We’ll use this project in the sections below to illustrate handling null responses in ASP.NET Core MVC.

Create a new controller in ASP.NET Core

In the Solution Explorer window, select the Controllers folder in the project, then right-click and choose Add->Controller to create a new controller. Specify the name of the controller class as DemoController. Next, replace the code of the DemoController class with the following code.

[Route("api/[controller]")]
    [ApiController]
    public class DemoController : ControllerBase
    {
        readonly Repository repository = new Repository();
        [HttpGet]
        public ActionResult Get()
        {
            string item = repository.GetMessage();
            return Ok(item);
        }
        [HttpGet("{id}", Name = "Get")]
        public IActionResult Get(int id)
        {
            string item = repository.GetMessage();
            return Ok(item);
        }
    }

Create a dummy Repository class in ASP.NET Core

Here is a dummy version of the Repository class that contains just one method that returns null. Of course this is only for illustrative purposes.

public class Repository
    {
        public string GetMessage()
        {
            return null;
        }
    }

How ASP.NET Core MVC handles null values

When you call the HttpGet endpoint of the DemoController shown above, the out-of-box behavior of ASP.NET Core MVC is to reply with HTTP Status Code 2014, i.e. “No Content,” as shown in the screen image given below.

aspnet core http status 2014 IDG

But why is this so? When sending back a response, the ASP.NET Core MVC framework attempts to select an output formatter from among the available formatters to handle the response object. Typically, this formatter can be a JSON formatter, an XML formatter, or any formatter appropriate to the media type.

However, when handling null values, the framework uses a different formatter. This formatter, called HttpNoContentOutputFormatte, is responsible for converting the null responses to HTTP Status Code 204, or the “No Content” response.

Disable the HttpNoContentOutputFormatter in ASP.NET Core

You can disable the default null value handling behavior in ASP.NET Core MVC by disabling the HttpNoContentOutputFormatter.

To do this, write the following code in the ConfigureServices method in the Startup class.

services.AddMvc(f =>
  {
      f.OutputFormatters.RemoveType
      (typeof(HttpNoContentOutputFormatter));
      f.OutputFormatters.Insert(0, new
      HttpNoContentOutputFormatter
      {
          TreatNullValueAsNoContent = false
      });
});

This will disable the HTTP Status Code 204 behavior. The response will now be HTTP Status Code 200, i.e. “OK,” with a null value written to the response object.

Return HTTP Status Code 404 in ASP.NET Core

Let’s update the controller’s action methods to return HTTP Status Code 404. Here is the updated version of the DemoController for your reference.

[Route("api/[controller]")]
    [ApiController]
    public class DemoController : ControllerBase
    {
        readonly Repository repository = new Repository();
        [HttpGet]
        public ActionResult Get()
        {
            string item = repository.GetMessage();
            if (item == null)
                return NotFound();
            return Ok(item);
        }      
    }

When you run the action method this time, HTTP Status Code 404, i.e. “Not Found,” is returned as shown in the screen image below.

aspnet core http status 404 IDG

A better way to return HTTP Status Code 404 in ASP.NET Core

A better option to return HTTP Status Code 404 is to use an action filter or a result filter.

public class NotFoundActionFilterAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuted(ActionExecutedContext context)
        {
            if (context.Result is ObjectResult)
            {
                ObjectResult objectResult = context.Result
                as ObjectResult;
                if (objectResult.Value == null)
                    context.Result = new NotFoundResult();
            }
        }
    }

You can then apply the filter at the action level, controller level, or global level. To apply the filter globally, write the following code in the ConfigureServices method of the Startup class.

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc(f =>
    {
        f.Filters.Add(new NotFoundResultFilterAttribute());
    });
}

When working with ASP.NET Core MVC, you can return data using IActionResult or ActionResult or any object. The framework does the necessary serialization when returning data from an action method.

However, when an action method returns a null value, ASP.NET Core MVC doesn’t attempt to serialize it using any of the available formatters. Rather, the framework returns an HTTP Status Code 204: success, no content. Fortunately, you can change this default behavior to suit your needs.

joydip_kanjilal
Contributor

Joydip Kanjilal is a Microsoft Most Valuable Professional (MVP) in ASP.NET, as well as a speaker and the author of several books and articles. He received the prestigious MVP award for 2007, 2008, 2009, 2010, 2011, and 2012.

He has more than 20 years of experience in IT, with more than 16 years in Microsoft .Net and related technologies. He has been selected as MSDN Featured Developer of the Fortnight (MSDN) and as Community Credit Winner several times.

He is the author of eight books and more than 500 articles. Many of his articles have been featured at Microsoft’s Official Site on ASP.Net.

He was a speaker at the Spark IT 2010 event and at the Dr. Dobb’s Conference 2014 in Bangalore. He has also worked as a judge for the Jolt Awards at Dr. Dobb's Journal. He is a regular speaker at the SSWUG Virtual Conference, which is held twice each year.

More from this author