Ray Cheng
Ray Cheng

Reputation: 12576

How to properly POST json data to Web API 2 actions

I have an ASP.NET MVC 5 web app that uses HTTP POST to send data to a ASP.NET Web API 2 action. The Web API action is hit, but the data are all null.

The POST is sent from:

var url = 'http://MyWebApi/api/MyController/MyAction/1';
var obj = { pamA: 'a', pamB: 1 };
var data = { json: ko.toJSON(obj) };
// var data = ko.toJSON(obj); // tried this too, but same problem.

$.ajax({
    type: 'post',
    dataType: 'json',
    url: url,
    data: data,
});

My Web API action is:

[System.Web.Http.HttpPost]
[System.Web.Http.Route("{id:int}")]
[ResponseType(typeof(Models.MyModel))]
[EnableCors(origins: "*", headers: "*", methods: "*")]
public IHttpActionResult Post(int id, Models.MyModel json){
  return Ok(200); // break point is hit but json doesn't have the data sent from client.
}

and my model is:

public class MyModel{
    public string pamA {get; set;}
    public int pamB {get; set;}
}

Upvotes: 0

Views: 577

Answers (2)

Chris Pratt
Chris Pratt

Reputation: 239290

For jQuery's ajax method, dataType specifies what you're expecting as a response, so you're probably still going to need that. The contentType option specifies how the request body is formatted and defaults to application/x-www-form-urlencoded, so you need to specify application/json instead.

$.ajax({
    type: 'post',
    dataType: 'json',
    contentType: 'application/json',
    url: url,
    data: data,
});

Upvotes: 1

victor
victor

Reputation: 812

First off I suggest for clarity that you mark where your parameters are coming from in your web action. Something like this

[System.Web.Http.HttpPost]
[System.Web.Http.Route("{id:int}")]
[ResponseType(typeof(Models.MyModel))]
[EnableCors(origins: "*", headers: "*", methods: "*")]
public IHttpActionResult Post([FromUri]int id, [FromBody]Models.MyModel json){
  return Ok(200); // break point is hit but json doesn't have the data sent from client.
}

Now that is not your problem, just me being obsessive. Anyways I think your problem is stemming from your ajax request.

var url = 'http://MyWebApi/api/MyController/MyAction/1';
var obj = { pamA: 'a', pamB: 1 };
var data = { json: ko.toJSON(obj) };

$.ajax({
    type: 'post',
    dataType: 'json',
    url: url,
    data: data,
});

should be:

var url = 'http://MyWebApi/api/MyController/MyAction/1';
var data = { pamA: 'a', pamB: 1 };

$.ajax({
    type: 'post',
    dataType: 'json',
    url: url,
    data: data,
});

Your MyModel object is expecting the json to have fields pamA and pamB. But your json object actually looks like this {"json": {"pamA":"a", "pamB":1} } Your json says that the object should contain a property called "json" that maps to an object with properties pamA and pamB. In order for your MyModel object to be able to map to the json your are currently sending it it would have to look like this.

public class OtherModel {
       public MyModel json;
}

But I suggest your just do away with the "json" field and make your json request look like this: { pamA: 'a', pamB: 1 }

Upvotes: 1

Related Questions