How to receive Json parameters from post request as JObject in ASP.NET Core 8.0 controller?

285 Views Asked by At

I have an application perfectly functioning, built in Angular 13 and .NET Core 2.1. Now I am upgrading it to .NET 8.0. I have successfully upgraded all other features, but I'm stuck at receiving the parameters as JObject.

In the old version, I pass the parameters from frontend in JSON like this:

"{ "query": "dotNet" }"

And the structure of backend controller action is as follows.

[HttpPost]
public async Task<IActionResult> GetDataAsync([FromBody] JObject jSearchItems)
{
     try
     {
         dynamic SearchItems = jSearchItems;
         string query = SearchItems.query;

         ServiceResponse response = await _Service.GetDataAsync(query);

         return StatusCode((int)(response.IsValid ? HttpStatusCode.OK : HttpStatusCode.BadRequest), response);
     }
     catch (Exception ex)
     {
         return StatusCode((int)HttpStatusCode.InternalServerError, ex.Message);
     }
}

Note that the type of function parameter is JObject.

In .NET core 2.1, this was working correctly, but when I upgraded it to .NET 8.0, the data is received as null in the controller method.

If I create a new model for parameters as follows:

class SearchItem
{
    public string query { get; set; }
}

and change the type of parameters from JObject to SearchItem, then the data is received correctly.

But I do not want to create hundreds of classes because there are a lot of API methods in this application.

So how can I receive JSON parameters from post request as JObject in ASP.NET Core 8.0 controllers?

2

There are 2 best solutions below

2
Mostafa Sabeghi On BEST ANSWER

Try this:

first install nuget package Microsoft.AspNetCore.Mvc.NewtonsoftJson and then in program.cs add:

builder.Services.AddControllers().AddNewtonsoftJson();
0
Jeevan ebi On

From ASP.NET Core 3.0 and later versions, the default JSON serializer used is System.Text.Json, which may behave differently compared to the Newtonsoft.Json library used in earlier versions. In your case, when receiving the JSON payload as JObject,System.Text.Json may not automatically bind the request body to a JObject object as Newtonsoft.Json did.

However, you can still achieve similar behavior by reading the request body as a string and then manually parsing it into a JObject. Here's how you can do it:

Ex:

[HttpPost]
public async Task<IActionResult> GetDataAsync()
{
    try
    {
        // Read the request body as a string
        using (StreamReader reader = new StreamReader(Request.Body, Encoding.UTF8))
        {
            string requestBody = await reader.ReadToEndAsync();
            
            JObject jSearchItems = JObject.Parse(requestBody);
            
            string query = (string)jSearchItems["query"];

            // ServiceResponse response = await _Service.GetDataAsync(query);

            return Ok(new { query }); 
        }
    }
    catch (Exception ex)
    {
        return StatusCode(500, ex.Message);
    }
}

This approach allows you to receive JSON parameters as JObject in ASP.NET Core 3.0 and later versions without explicitly defining a model class for each API endpoint.