[c#] ASP.NET Core return JSON with status code

I'm looking for the correct way to return JSON with a HTTP status code in my .NET Core Web API controller. I use to use it like this:

public IHttpActionResult GetResourceData()
{
    return this.Content(HttpStatusCode.OK, new { response = "Hello"});
}

This was in a 4.6 MVC application but now with .NET Core I don't seem to have this IHttpActionResult I have ActionResult and using like this:

public ActionResult IsAuthenticated()
{
    return Ok(Json("123"));
}

But the response from the server is weird, as in the image below:

enter image description here

I just want the Web API controller to return JSON with a HTTP status code like I did in Web API 2.

This question is related to c# json asp.net-core asp.net-core-webapi

The answer is


The most basic version responding with a JsonResult is:

// GET: api/authors
[HttpGet]
public JsonResult Get()
{
    return Json(_authorRepository.List());
}

However, this isn't going to help with your issue because you can't explicitly deal with your own response code.

The way to get control over the status results, is you need to return a ActionResult which is where you can then take advantage of the StatusCodeResult type.

for example:

// GET: api/authors/search?namelike=foo
[HttpGet("Search")]
public IActionResult Search(string namelike)
{
    var result = _authorRepository.GetByNameSubstring(namelike);
    if (!result.Any())
    {
        return NotFound(namelike);
    }
    return Ok(result);
}

Note both of these above examples came from a great guide available from Microsoft Documentation: Formatting Response Data


Extra Stuff

The issue I come across quite often is that I wanted more granular control over my WebAPI rather than just go with the defaults configuration from the "New Project" template in VS.

Let's make sure you have some of the basics down...

Step 1: Configure your Service

In order to get your ASP.NET Core WebAPI to respond with a JSON Serialized Object along full control of the status code, you should start off by making sure that you have included the AddMvc() service in your ConfigureServices method usually found in Startup.cs.

It's important to note thatAddMvc() will automatically include the Input/Output Formatter for JSON along with responding to other request types.

If your project requires full control and you want to strictly define your services, such as how your WebAPI will behave to various request types including application/json and not respond to other request types (such as a standard browser request), you can define it manually with the following code:

public void ConfigureServices(IServiceCollection services)
{
    // Build a customized MVC implementation, without using the default AddMvc(), instead use AddMvcCore().
    // https://github.com/aspnet/Mvc/blob/dev/src/Microsoft.AspNetCore.Mvc/MvcServiceCollectionExtensions.cs

    services
        .AddMvcCore(options =>
        {
            options.RequireHttpsPermanent = true; // does not affect api requests
            options.RespectBrowserAcceptHeader = true; // false by default
            //options.OutputFormatters.RemoveType<HttpNoContentOutputFormatter>();

            //remove these two below, but added so you know where to place them...
            options.OutputFormatters.Add(new YourCustomOutputFormatter()); 
            options.InputFormatters.Add(new YourCustomInputFormatter());
        })
        //.AddApiExplorer()
        //.AddAuthorization()
        .AddFormatterMappings()
        //.AddCacheTagHelper()
        //.AddDataAnnotations()
        //.AddCors()
        .AddJsonFormatters(); // JSON, or you can build your own custom one (above)
}

You will notice that I have also included a way for you to add your own custom Input/Output formatters, in the event you may want to respond to another serialization format (protobuf, thrift, etc).

The chunk of code above is mostly a duplicate of the AddMvc() method. However, we are implementing each "default" service on our own by defining each and every service instead of going with the pre-shipped one with the template. I have added the repository link in the code block, or you can check out AddMvc() from the GitHub repository..

Note that there are some guides that will try to solve this by "undoing" the defaults, rather than just not implementing it in the first place... If you factor in that we're now working with Open Source, this is redundant work, bad code and frankly an old habit that will disappear soon.


Step 2: Create a Controller

I'm going to show you a really straight-forward one just to get your question sorted.

public class FooController
{
    [HttpPost]
    public async Task<IActionResult> Create([FromBody] Object item)
    {
        if (item == null) return BadRequest();

        var newItem = new Object(); // create the object to return
        if (newItem != null) return Ok(newItem);

        else return NotFound();
    }
}

Step 3: Check your Content-Type and Accept

You need to make sure that your Content-Type and Accept headers in your request are set properly. In your case (JSON), you will want to set it up to be application/json.

If you want your WebAPI to respond as JSON as default, regardless of what the request header is specifying you can do that in a couple ways.

Way 1 As shown in the article I recommended earlier (Formatting Response Data) you could force a particular format at the Controller/Action level. I personally don't like this approach... but here it is for completeness:

Forcing a Particular Format If you would like to restrict the response formats for a specific action you can, you can apply the [Produces] filter. The [Produces] filter specifies the response formats for a specific action (or controller). Like most Filters, this can be applied at the action, controller, or global scope.

[Produces("application/json")]
public class AuthorsController

The [Produces] filter will force all actions within the AuthorsController to return JSON-formatted responses, even if other formatters were configured for the application and the client provided an Accept header requesting a different, available format.

Way 2 My preferred method is for the WebAPI to respond to all requests with the format requested. However, in the event that it doesn't accept the requested format, then fall-back to a default (ie. JSON)

First, you'll need to register that in your options (we need to rework the default behavior, as noted earlier)

options.RespectBrowserAcceptHeader = true; // false by default

Finally, by simply re-ordering the list of the formatters that were defined in the services builder, the web host will default to the formatter you position at the top of the list (ie position 0).

More information can be found in this .NET Web Development and Tools Blog entry


You have predefined methods for most common status codes.

  • Ok(result) returns 200 with response
  • CreatedAtRoute returns 201 + new resource URL
  • NotFound returns 404
  • BadRequest returns 400 etc.

See BaseController.cs and Controller.cs for a list of all methods.

But if you really insist you can use StatusCode to set a custom code, but you really shouldn't as it makes code less readable and you'll have to repeat code to set headers (like for CreatedAtRoute).

public ActionResult IsAuthenticated()
{
    return StatusCode(200, "123");
}

With ASP.NET Core 2.0, the ideal way to return object from Web API (which is unified with MVC and uses same base class Controller) is

public IActionResult Get()
{
    return new OkObjectResult(new Item { Id = 123, Name = "Hero" });
}

Notice that

  1. It returns with 200 OK status code (it's an Ok type of ObjectResult)
  2. It does content negotiation, i.e. it'll return based on Accept header in request. If Accept: application/xml is sent in request, it'll return as XML. If nothing is sent, JSON is default.

If it needs to send with specific status code, use ObjectResult or StatusCode instead. Both does the same thing, and supports content negotiation.

return new ObjectResult(new Item { Id = 123, Name = "Hero" }) { StatusCode = 200 };
return StatusCode( 200, new Item { Id = 123, Name = "Hero" });

or even more fine grained with ObjectResult:

 Microsoft.AspNetCore.Mvc.Formatters.MediaTypeCollection myContentTypes = new Microsoft.AspNetCore.Mvc.Formatters.MediaTypeCollection { System.Net.Mime.MediaTypeNames.Application.Json };
 String hardCodedJson = "{\"Id\":\"123\",\"DateOfRegistration\":\"2012-10-21T00:00:00+05:30\",\"Status\":0}";
 return new ObjectResult(hardCodedJson) { StatusCode = 200, ContentTypes = myContentTypes };

If you specifically want to return as JSON, there are couple of ways

//GET http://example.com/api/test/asjson
[HttpGet("AsJson")]
public JsonResult GetAsJson()
{
    return Json(new Item { Id = 123, Name = "Hero" });
}

//GET http://example.com/api/test/withproduces
[HttpGet("WithProduces")]
[Produces("application/json")]
public Item GetWithProduces()
{
    return new Item { Id = 123, Name = "Hero" };
}

Notice that

  1. Both enforces JSON in two different ways.
  2. Both ignores content negotiation.
  3. First method enforces JSON with specific serializer Json(object).
  4. Second method does the same by using Produces() attribute (which is a ResultFilter) with contentType = application/json

Read more about them in the official docs. Learn about filters here.

The simple model class that is used in the samples

public class Item
{
    public int Id { get; set; }
    public string Name { get; set; }
}

The easiest way I came up with is :

var result = new Item { Id = 123, Name = "Hero" };

return new JsonResult(result)
{
    StatusCode = StatusCodes.Status201Created // Status code here 
};

This is my easiest solution:

public IActionResult InfoTag()
{
    return Ok(new {name = "Fabio", age = 42, gender = "M"});
}

or

public IActionResult InfoTag()
{
    return Json(new {name = "Fabio", age = 42, gender = "M"});
}

Instead of using 404/201 status codes using enum

     public async Task<IActionResult> Login(string email, string password)
    {
        if (string.IsNullOrWhiteSpace(email) || string.IsNullOrWhiteSpace(password))
        { 
            return StatusCode((int)HttpStatusCode.BadRequest, Json("email or password is null")); 
        }

        var user = await _userManager.FindByEmailAsync(email);
        if (user == null)
        {
            return StatusCode((int)HttpStatusCode.BadRequest, Json("Invalid Login and/or password"));

        }
        var passwordSignInResult = await _signInManager.PasswordSignInAsync(user, password, isPersistent: true, lockoutOnFailure: false);
        if (!passwordSignInResult.Succeeded)
        {
            return StatusCode((int)HttpStatusCode.BadRequest, Json("Invalid Login and/or password"));
        }
        return StatusCode((int)HttpStatusCode.OK, Json("Sucess !!!"));
    }

Awesome answers I found here and I also tried this return statement see StatusCode(whatever code you wish) and it worked!!!

return Ok(new {
                    Token = new JwtSecurityTokenHandler().WriteToken(token),
                    Expiration = token.ValidTo,
                    username = user.FullName,
                    StatusCode = StatusCode(200)
                });

Controller action return types in ASP.NET Core web API 02/03/2020

6 minutes to read +2

By Scott Addie Link

Synchronous action

[HttpGet("{id}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public ActionResult<Product> GetById(int id)
{
    if (!_repository.TryGetProduct(id, out var product))
    {
        return NotFound();
    }

    return product;
}

Asynchronous action

[HttpPost]
[Consumes(MediaTypeNames.Application.Json)]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public async Task<ActionResult<Product>> CreateAsync(Product product)
{
    if (product.Description.Contains("XYZ Widget"))
    {
        return BadRequest();
    }

    await _repository.AddProductAsync(product);

    return CreatedAtAction(nameof(GetById), new { id = product.Id }, product);
}

The cleanest solution I have found is to set the following in my ConfigureServices method in Startup.cs (In my case I want the TZ info stripped. I always want to see the date time as the user saw it).

   services.AddControllers()
                .AddNewtonsoftJson(o =>
                {
                    o.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Unspecified;
                });

The DateTimeZoneHandling options are Utc, Unspecified, Local or RoundtripKind

I would still like to find a way to be able to request this on a per-call bases.

something like

  static readonly JsonMediaTypeFormatter _jsonFormatter = new JsonMediaTypeFormatter();
 _jsonFormatter.SerializerSettings = new JsonSerializerSettings()
                {DateTimeZoneHandling = DateTimeZoneHandling.Unspecified};

return Ok("Hello World", _jsonFormatter );

I am converting from ASP.NET and there I used the following helper method

public static ActionResult<T> Ok<T>(T result, HttpContext context)
    {
        var responseMessage = context.GetHttpRequestMessage().CreateResponse(HttpStatusCode.OK, result, _jsonFormatter);
        return new ResponseMessageResult(responseMessage);
    }

I got this to work. My big issue was my json was a string (in my database...and not a specific/known Type).

Ok, I finally got this to work.

////[Route("api/[controller]")]
////[ApiController]
////public class MyController: Microsoft.AspNetCore.Mvc.ControllerBase
////{
                    //// public IActionResult MyMethod(string myParam) {

                    string hardCodedJson = "{}";
                    int hardCodedStatusCode = 200;

                    Newtonsoft.Json.Linq.JObject job = Newtonsoft.Json.Linq.JObject.Parse(hardCodedJson);
                    /* "this" comes from your class being a subclass of Microsoft.AspNetCore.Mvc.ControllerBase */
                    Microsoft.AspNetCore.Mvc.ContentResult contRes = this.Content(job.ToString());
                    contRes.StatusCode = hardCodedStatusCode;

                    return contRes;

                    //// } ////end MyMethod
              //// } ////end class

I happen to be on asp.net core 3.1

#region Assembly Microsoft.AspNetCore.Mvc.Core, Version=3.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60
//C:\Program Files\dotnet\packs\Microsoft.AspNetCore.App.Ref\3.1.0\ref\netcoreapp3.1\Microsoft.AspNetCore.Mvc.Core.dll

I got the hint from here :: https://www.jianshu.com/p/7b3e92c42b61


Please refer below code, You can manage multiple status code with different type JSON

public async Task<HttpResponseMessage> GetAsync()
{
    try
    {
        using (var entities = new DbEntities())
        {
            var resourceModelList = entities.Resources.Select(r=> new ResourceModel{Build Your Resource Model}).ToList();

            if (resourceModelList.Count == 0)
            {
                return this.Request.CreateResponse<string>(HttpStatusCode.NotFound, "No resources found.");
            }

            return this.Request.CreateResponse<List<ResourceModel>>(HttpStatusCode.OK, resourceModelList, "application/json");
        }
    }
    catch (Exception ex)
    {
        return this.Request.CreateResponse<string>(HttpStatusCode.InternalServerError, "Something went wrong.");
    }
}

What I do in my Asp Net Core Api applications it is to create a class that extends from ObjectResult and provide many constructors to customize the content and the status code. Then all my Controller actions use one of the costructors as appropiate. You can take a look at my implementation at: https://github.com/melardev/AspNetCoreApiPaginatedCrud

and

https://github.com/melardev/ApiAspCoreEcommerce

here is how the class looks like(go to my repo for full code):

public class StatusCodeAndDtoWrapper : ObjectResult
{



    public StatusCodeAndDtoWrapper(AppResponse dto, int statusCode = 200) : base(dto)
    {
        StatusCode = statusCode;
    }

    private StatusCodeAndDtoWrapper(AppResponse dto, int statusCode, string message) : base(dto)
    {
        StatusCode = statusCode;
        if (dto.FullMessages == null)
            dto.FullMessages = new List<string>(1);
        dto.FullMessages.Add(message);
    }

    private StatusCodeAndDtoWrapper(AppResponse dto, int statusCode, ICollection<string> messages) : base(dto)
    {
        StatusCode = statusCode;
        dto.FullMessages = messages;
    }
}

Notice the base(dto) you replace dto by your object and you should be good to go.


Questions with c# tag:

How can I convert this one line of ActionScript to C#? Microsoft Advertising SDK doesn't deliverer ads How to use a global array in C#? How to correctly write async method? C# - insert values from file into two arrays Uploading into folder in FTP? Are these methods thread safe? dotnet ef not found in .NET Core 3 HTTP Error 500.30 - ANCM In-Process Start Failure Best way to "push" into C# array How can I add raw data body to an axios request? Couldn't process file resx due to its being in the Internet or Restricted zone or having the mark of the web on the file Convert string to boolean in C# Entity Framework Core: A second operation started on this context before a previous operation completed ASP.NET Core - Swashbuckle not creating swagger.json file Is ConfigurationManager.AppSettings available in .NET Core 2.0? No authenticationScheme was specified, and there was no DefaultChallengeScheme found with default authentification and custom authorization Getting value from appsettings.json in .net core .net Core 2.0 - Package was restored using .NetFramework 4.6.1 instead of target framework .netCore 2.0. The package may not be fully compatible Automatically set appsettings.json for dev and release environments in asp.net core? How to use log4net in Asp.net core 2.0 Get ConnectionString from appsettings.json instead of being hardcoded in .NET Core 2.0 App Unable to create migrations after upgrading to ASP.NET Core 2.0 Update .NET web service to use TLS 1.2 Using app.config in .Net Core How to send json data in POST request using C# ASP.NET Core form POST results in a HTTP 415 Unsupported Media Type response How to enable CORS in ASP.net Core WebAPI VS 2017 Metadata file '.dll could not be found How to set combobox default value? How to get root directory of project in asp.net core. Directory.GetCurrentDirectory() doesn't seem to work correctly on a mac ALTER TABLE DROP COLUMN failed because one or more objects access this column Error: the entity type requires a primary key How to POST using HTTPclient content type = application/x-www-form-urlencoded CORS: credentials mode is 'include' Visual Studio 2017: Display method references Where is NuGet.Config file located in Visual Studio project? Unity Scripts edited in Visual studio don't provide autocomplete How to create roles in ASP.NET Core and assign them to users? Return file in ASP.Net Core Web API ASP.NET Core return JSON with status code auto create database in Entity Framework Core Class Diagrams in VS 2017 How to read/write files in .Net Core? How to read values from the querystring with ASP.NET Core? how to set ASPNETCORE_ENVIRONMENT to be considered for publishing an asp.net core application? ASP.NET Core Get Json Array using IConfiguration Entity Framework Core add unique constraint code-first No templates in Visual Studio 2017 ps1 cannot be loaded because running scripts is disabled on this system

Questions with json tag:

Use NSInteger as array index Uncaught SyntaxError: Unexpected end of JSON input at JSON.parse (<anonymous>) HTTP POST with Json on Body - Flutter/Dart Importing json file in TypeScript json.decoder.JSONDecodeError: Extra data: line 2 column 1 (char 190) Angular 5 Service to read local .json file How to import JSON File into a TypeScript file? Use Async/Await with Axios in React.js Uncaught SyntaxError: Unexpected token u in JSON at position 0 how to remove json object key and value.? JSON parse error: Can not construct instance of java.time.LocalDate: no String-argument constructor/factory method to deserialize from String value How to format JSON in notepad++ No String-argument constructor/factory method to deserialize from String value ('') Returning JSON object as response in Spring Boot TypeError: Object of type 'bytes' is not JSON serializable How to send json data in POST request using C# Passing headers with axios POST request How to convert JSON string into List of Java object? npm notice created a lockfile as package-lock.json. You should commit this file RestClientException: Could not extract response. no suitable HttpMessageConverter found Load json from local file with http.get() in angular 2 Angular: 'Cannot find a differ supporting object '[object Object]' of type 'object'. NgFor only supports binding to Iterables such as Arrays' How to loop through a JSON object with typescript (Angular2) How to push JSON object in to array using javascript How to check if a key exists in Json Object and get its value REST API - Use the "Accept: application/json" HTTP Header react router v^4.0.0 Uncaught TypeError: Cannot read property 'location' of undefined ASP.NET Core return JSON with status code python JSON object must be str, bytes or bytearray, not 'dict Writing JSON object to a JSON file with fs.writeFileSync Convert a JSON Object to Buffer and Buffer to JSON Object back How to parse JSON in Kotlin? How to convert FormData (HTML5 object) to JSON console.log(result) returns [object Object]. How do I get result.name? tsconfig.json: Build:No inputs were found in config file Python - How to convert JSON File to Dataframe How to define Typescript Map of key value pair. where key is a number and value is an array of objects Retrofit 2: Get JSON from Response body Refused to execute script, strict MIME type checking is enabled? Decode JSON with unknown structure How to parse a JSON object to a TypeScript Object Deserialize Java 8 LocalDateTime with JacksonMapper Getting an object array from an Angular service Python - Convert a bytes array into JSON format Passing bash variable to jq Use JsonReader.setLenient(true) to accept malformed JSON at line 1 column 1 path $ What is the difference between json.load() and json.loads() functions Import JSON file in React using setTimeout on promise chain Make XmlHttpRequest POST using JSON

Questions with asp.net-core tag:

dotnet ef not found in .NET Core 3 How to use Bootstrap 4 in ASP.NET Core ASP.NET Core - Swashbuckle not creating swagger.json file Getting value from appsettings.json in .net core .net Core 2.0 - Package was restored using .NetFramework 4.6.1 instead of target framework .netCore 2.0. The package may not be fully compatible Automatically set appsettings.json for dev and release environments in asp.net core? Get ConnectionString from appsettings.json instead of being hardcoded in .NET Core 2.0 App Unable to create migrations after upgrading to ASP.NET Core 2.0 EF Core add-migration Build Failed ASP.NET Core form POST results in a HTTP 415 Unsupported Media Type response How to enable CORS in ASP.net Core WebAPI How to get root directory of project in asp.net core. Directory.GetCurrentDirectory() doesn't seem to work correctly on a mac Entity Framework Core: DbContextOptionsBuilder does not contain a definition for 'usesqlserver' and no extension method 'usesqlserver' Visual Studio 2017 error: Unable to start program, An operation is not legal in the current state The default XML namespace of the project must be the MSBuild XML namespace How to create roles in ASP.NET Core and assign them to users? Return file in ASP.Net Core Web API ASP.NET Core return JSON with status code How to read values from the querystring with ASP.NET Core? how to set ASPNETCORE_ENVIRONMENT to be considered for publishing an asp.net core application? ASP.NET Core Get Json Array using IConfiguration Rebuild Docker container on file changes tsconfig.json: Build:No inputs were found in config file ASP.NET Core Dependency Injection error: Unable to resolve service for type while attempting to activate How to read request body in an asp.net core webapi controller? How to set up Automapper in ASP.NET Core How do I access Configuration in any class in ASP.NET Core? How to register multiple implementations of the same interface in Asp.Net Core? ASP.NET Core Web API Authentication How to change the port number for Asp.Net core app? ASP.NET Core Identity - get current user ASP.NET Core Web API exception handling ASP.NET Core 1.0 on IIS error 502.5 How to get HttpContext.Current in ASP.NET Core? How to determine if .NET Core is installed How to get current url in view in asp.net core 1.0 'No database provider has been configured for this DbContext' on SignInManager.PasswordSignInAsync How to unapply a migration in ASP.NET Core with EF Core The term "Add-Migration" is not recognized bypass invalid SSL certificate in .net core AddTransient, AddScoped and AddSingleton Services Differences How to use npm with ASP.NET Core How to return HTTP 500 from ASP.NET Core RC2 Web Api? Send HTTP POST message in ASP.NET Core using HttpClient PostAsJsonAsync How to return a specific status code and no contents from Controller? How to specify the port an ASP.NET Core application is hosted on? How to get current user in asp.net core How to pass multiple parameters to a get method in ASP.NET Core Custom Authentication in ASP.Net-Core How to use SqlClient in ASP.NET Core?

Questions with asp.net-core-webapi tag:

Return file in ASP.Net Core Web API ASP.NET Core return JSON with status code RS256 vs HS256: What's the difference? How to return a specific status code and no contents from Controller?