Pass json data to ASP.Net core 2 web api

Viewed 4859

I know that this question has been asked several times, but none of the previous solutions helped me out with my problem (that seems a pretty simple one actually). I just want to send a Json object to a Post method that I created in a controller class. Here's the interesting portion of my controller class:

[Route("api/[controller]")]
public class CodeController : Controller
{
    [HttpPost]
    public void Post([FromBody] InfoNegozio value)
    {
       return;
    }
}

I kept it simple as I just want the value to be set properly. Here's the class InfoNegozio:

public class InfoNegozio
    {
        public int IdNegozio { get; set; }
        public string NomeNegozio { get; set; }
        public int AttesaStimata { get; set; }
        public DateTime UltimoAggiornamento { get; set; }
    }

This is the code used to send data to this API:

var myData = { "IdNegozio": idNegozio, "AttesaStimata": tempoAttesa };
    $.ajax({
        url: "api/Code",
        type: "POST",
        contentType: "application/json",
        dataType: "json",
        data: JSON.stringify(myData)
});

The JQuery code just call the webapi controller, the value field is a not null InfoNegozio object, but the field IdNegozio and AttesaStimata are always 0.

I could ask that I'm using a controller in a Razor Page project, and I had to add this line of code in the Startup.Configure method in order to make it work (with "it" I meant the other webapi GET methods).

app.UseEndpoints(endpoints => { endpoints.MapControllers(); });

Any Idea?

Edited

Using postman I figured out what the difference is between a wroking call and a not working one. The posting this json with postman is works:

{
    "IdNegozio": 1,
    "AttesaStimata": 36
}

Unfortunately, with jquery, using JSON.stringify, I get this (note the double quote on the values):

 {
     "IdNegozio": "1",
     "AttesaStimata": "36"
 }

And this don't work! Are Json stringify incompatible with .net core Web Api? Is it possible there isn't a clean approach to make those 2 libraries work together?

Edited 2

I ended up building the json manually, forcing jquery to sent "my version", so my js code is now looking:

var myData = '{ "IdNegozio": '+idNegozio+', "AttesaStimata": '+tempoAttesa+' }';
    $.ajax({
        url: "api/Code",
        type: "POST",
        contentType: "application/json",
        dataType: "json",
        data: myData
});

Anyway I don't like this solution as it seems I'm not using the right way to build the json object, so any smarter solution would be much appreciated.

2 Answers

Creating an answer so we don't have a million comments on your post. This is a ASP.NET Core 3.1 Web API project, correct ? If so, try making these couple of changes and see if that fixes the issue.

Inherit from ControllerBase rather than the full Controller class. Also add the [ApiController] attribute to your CodeController class. Then for your Post action, remove the [FromBody] attribute from your InfoNegozio parameter. Like this :

[Route("api/[controller]")]
[ApiController]
public class CodeController : ControllerBase
{
    [HttpPost]
    public IActionResult Post(InfoNegozio value)
    {
       return Ok(value);
    }
}

See if that fixes anything. Something is getting screwed up during model binding, which leads me to believe that your JSON Serialization configuration is messed up. If you can post your Startup.cs, then we can see if there may be a configuration error. I just opened up a .NET Core 3.1 Web API project and tested one of my controllers and it works as expected. So give that a shot and see if maybe that fixes it. These items will affect how the controller is configured, so if it is an API controller, handling standard API requests (application/json) then it should be configured as such. You can read the specifics on the ASP.NET Core 3.1 docs but having this setup properly as an API Controller is going to make sure your JSON requests are properly serialized. Right now you have it set up like an MVC controller which is likely why you're running into issues.

Edit: Also, consider returning an IActionResult from your controller action. Might make testing easier as you can actually receive a response that will help you find the error. Then simply just change return; to return Ok(); Updated code sample to reflect this.

If you want to write like the first way you provided, you can use parseInt to ensure that int type data is passed.

Try this code:

      var myData = { "IdNegozio": parseInt(idNegozio), "AttesaStimata": parseInt(tempoAttesa) };
        $.ajax({
            url: "api/Code",
            type: "POST",
            contentType: "application/json",
            dataType: "json",
           data: JSON.stringify(myData) 
        });

There is also another choice (if you used core 3.x version):

  • Install Microsoft.AspNetCore.Mvc.NewtonsoftJson -Version 3.x library

  • Add services.AddControllersWithViews().AddNewtonsoftJson(); in
    ConfigureServices in startup.cs.

After these two steps, you can use the json format you used at the beginning.

var myData = { "IdNegozio": idNegozio, "AttesaStimata": tempoAttesa };
                        $.ajax({
                            url: "api/ApiCode",
                            type: "POST",
                            contentType: "application/json",
                            dataType: "json",
                           data: JSON.stringify(myData)

                        });
Related