How to pass json POST data to Web API method as an object?
EDIT : 31/10/2017
The same code/approach will work for Asp.Net Core 2.0 as well. The major difference is, In asp.net core, both web api controllers and Mvc controllers are merged together to single controller model. So your return type might be IActionResult
or one of it's implementation (Ex :OkObjectResult
)
Use
contentType:"application/json"
You need to use JSON.stringify
method to convert it to JSON string when you send it,
And the model binder will bind the json data to your class object.
The below code will work fine (tested)
$(function () {
var customer = {contact_name :"Scott",company_name:"HP"};
$.ajax({
type: "POST",
data :JSON.stringify(customer),
url: "api/Customer",
contentType: "application/json"
});
});
Result
contentType
property tells the server that we are sending the data in JSON format. Since we sent a JSON data structure,model binding will happen properly.
If you inspect the ajax request's headers, you can see that the Content-Type
value is set as application/json
.
If you do not specify contentType explicitly, It will use the default content type which is application/x-www-form-urlencoded;
Edit on Nov 2015 to address other possible issues raised in comments
Posting a complex object
Let's say you have a complex view model class as your web api action method parameter like this
public class CreateUserViewModel
{
public int Id {set;get;}
public string Name {set;get;}
public List<TagViewModel> Tags {set;get;}
}
public class TagViewModel
{
public int Id {set;get;}
public string Code {set;get;}
}
and your web api end point is like
public class ProductController : Controller
{
[HttpPost]
public CreateUserViewModel Save([FromBody] CreateUserViewModel m)
{
// I am just returning the posted model as it is.
// You may do other stuff and return different response.
// Ex : missileService.LaunchMissile(m);
return m;
}
}
At the time of this writing, ASP.NET MVC 6 is the latest stable version and in MVC6, Both Web api controllers and MVC controllers are inheriting from Microsoft.AspNet.Mvc.Controller
base class.
To send data to the method from client side, the below code should work fine
//Build an object which matches the structure of our view model class
var model = {
Name: "Shyju",
Id: 123,
Tags: [{ Id: 12, Code: "C" }, { Id: 33, Code: "Swift" }]
};
$.ajax({
type: "POST",
data: JSON.stringify(model),
url: "../product/save",
contentType: "application/json"
}).done(function(res) {
console.log('res', res);
// Do something with the result :)
});
Model binding works for some properties, but not all ! Why ?
If you do not decorate the web api method parameter with [FromBody]
attribute
[HttpPost]
public CreateUserViewModel Save(CreateUserViewModel m)
{
return m;
}
And send the model(raw javascript object, not in JSON format) without specifying the contentType property value
$.ajax({
type: "POST",
data: model,
url: "../product/save"
}).done(function (res) {
console.log('res', res);
});
Model binding will work for the flat properties on the model, not the properties where the type is complex/another type. In our case, Id
and Name
properties will be properly bound to the parameter m
, But the Tags
property will be an empty list.
The same problem will occur if you are using the short version, $.post
which will use the default Content-Type when sending the request.
$.post("../product/save", model, function (res) {
//res contains the markup returned by the partial view
console.log('res', res);
});
Pass JSON object to WebApi
Will take only one minute, give this a try:
$.post("api/registration",
registrationData,
function (value) {
$('#registrationMessage').append(value);
},
"json"
);
How to pass JSON as parameter to Post method in controller .net api
When you are checking if device if exist you are using a wrong Id, you have to use DeviceId instead
var exist = deviceContext.Devices.Any(i=> i.Id==deviceData.DeviceId);
if (!exist) return BadRequest(Messages.DeviceNotExist);
and IMHO, replace
deviceContext.DeviceData.Add(new DeviceData
{
Timestamp = DateTime.Now,
Latitude = deviceData.Latitude,
Longitude = deviceData.Longitude,
Altitude = deviceData.Altitude,
Speed = deviceData.Speed,
DeviceId = deviceData.DeviceId
});
with
deviceData.Timestamp = DateTime.Now;
deviceContext.DeviceData.Add(deviceData);
Passing JSON Object to GET Method - ASP.Net ApiController
Change [HttpGet]
to [HttpPost]
. GET's can't have a [FromBody]
parameter:
[Route("file")]
[HttpPost]
public async Task<IHttpActionResult> DownloadFile([FromBody] UriWeb uri){...}
If you have to use GET, then you need to pass it as a Query String. So you would change it to:
[Route("file")]
[HttpGet]
public async Task<IHttpActionResult> DownloadFile([FromQuery] Uri uri){...}
And then call it as so (query string has been encoded):
http://example.com/api/file?uri=http%3A%2F%2Fexample.com%2Ffile.zip
Post JSON data to web API using object in C#
Thanks to Mason! I wrote the code to POST the data to the web API using HttpWebRequest
.
Main
static void Main(string[] args)
{
string patientServiceResponse = PostRequest( string.Format("https://url.com/api/{0}/{1}/taskOrders", 3345, "1V34858493"));
Debug.Write(patientServiceResponse);
}
POST
private static string PostRequest(string url)
{
HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
httpWebRequest.ContentType = "application/json; charset=utf-8";
httpWebRequest.Method = "POST";
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
string json = "[ { \"ReferenceId\": \"a123\" } ]";
Debug.Write(json);
streamWriter.Write(json);
streamWriter.Flush();
streamWriter.Close();
}
try
{
using (var response = httpWebRequest.GetResponse() as HttpWebResponse)
{
if (httpWebRequest.HaveResponse && response != null)
{
using (var reader = new StreamReader(response.GetResponseStream()))
{
result = reader.ReadToEnd();
}
}
}
}
catch (WebException e)
{
if (e.Response != null)
{
using (var errorResponse = (HttpWebResponse)e.Response)
{
using (var reader = new StreamReader(errorResponse.GetResponseStream()))
{
string error = reader.ReadToEnd();
result = error;
}
}
}
}
return result;
}
Post json data in body to web api
WebAPI is working as expected because you're telling it that you're sending this json object:
{ "username":"admin", "password":"admin" }
Then you're asking it to deserialize it as a string
which is impossible since it's not a valid JSON string.
Solution 1:
If you want to receive the actual JSON as in the value of value
will be:
value = "{ \"username\":\"admin\", \"password\":\"admin\" }"
then the string you need to set the body of the request in postman to is:
"{ \"username\":\"admin\", \"password\":\"admin\" }"
Solution 2 (I'm assuming this is what you want):
Create a C# object that matches the JSON so that WebAPI can deserialize it properly.
First create a class that matches your JSON:
public class Credentials
{
[JsonProperty("username")]
public string Username { get; set; }
[JsonProperty("password")]
public string Password { get; set; }
}
Then in your method use this:
[Route("api/account/GetToken/")]
[System.Web.Http.HttpPost]
public HttpResponseBody GetToken([FromBody] Credentials credentials)
{
string username = credentials.Username;
string password = credentials.Password;
}
Posting JSON object via AJAX to ASP.NET Core Web API
I opened the Network tab and I got this: I got a 404 (kind of
expected that) , the name of the method 'save' , a type of 'xhr' and a
size of 45B.
The 404 error obviously means the url/routing is wrong. Here to solve it ,you have two ways to achieve.
First way:
You can change url to "api/shopping" in ajax as follow:
$.ajax({
type: "POST",
data: JSON.stringify(shoppingCart),
url: "api/shopping",
contentType: "application/json charset=utf-8",
}).done(function (res) {
alert(res);
})
Second way:
You can change the path name
of Save
action by Attribute routing with Http verb attributes as follow:
[Route("api/Shopping")]
[ApiController]
public class ShoppingCartController : ControllerBase
{
[HttpPost("Save")]
public ShoppingCart Save([FromBody] ShoppingCart s)
{
return s;
}
}
Update
According to your comment, in addition to the above updates, you also need to modify the routing settings as follows:
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
Debug result:
Related Topics
How to Access Iframe Elements with JavaScript
Asynchronously Load Images with Jquery
Browsers, Time Zones, Chrome 67 Error (Historic Timezone Changes)
How to Replace Innerhtml of a Div Using Jquery
Read Environment Variables in Node.Js
Check Whether a String Matches a Regex in Js
How to Detect Pressing Enter on the Keyboard Using Jquery
How to Use JavaScript to Change the Meta-Tags of the Page
JavaScript Scroll Event for Iphone/Ipad
Why Doesn't Equality Check Work with Arrays
Call an Asynchronous JavaScript Function Synchronously
Issue in Returning Data Retrieved from Db Queries Called in the Loop
How to Pass Data from a Page to Another Page Using React Router
Parseint VS Unary Plus, When to Use Which
Does React Keep the Order for State Updates
When to Use Es6 Class Based React Components VS. Functional Es6 React Components