Simple Post to Web API

Simple post to Web Api

It's been quite sometime since I asked this question. Now I understand it more clearly, I'm going to put a more complete answer to help others.

In Web API, it's very simple to remember how parameter binding is happening.

  • if you POST simple types, Web API tries to bind it from the URL
  • if you POST complex type, Web API tries to bind it from the body of
    the request (this uses a media-type formatter).

  • If you want to bind a complex type from the URL, you'll use [FromUri] in your action parameter. The limitation of this is down to how long your data going to be and if it exceeds the url character limit.

    public IHttpActionResult Put([FromUri] ViewModel data) { ... }

  • If you want to bind a simple type from the request body, you'll use [FromBody] in your action parameter.

    public IHttpActionResult Put([FromBody] string name) { ... }

as a side note, say you are making a PUT request (just a string) to update something. If you decide not to append it to the URL and pass as a complex type with just one property in the model, then the data parameter in jQuery ajax will look something like below. The object you pass to data parameter has only one property with empty property name.

var myName = 'ABC';
$.ajax({url:.., data: {'': myName}});

and your web api action will look something like below.

public IHttpActionResult Put([FromBody] string name){ ... }

This asp.net page explains it all.
http://www.asp.net/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api

Making a simple Web API post request

Hitting a URL in your browser will only do a GET request.

You can either:

  • create a simple <form> with its method set to POST and form inputs to enter the values you want to send (like NewValue), OR
  • write some JavaScript to create an AJAX POST request using your favorite framework, OR
  • Use a tool like Postman to set up a POST request, invoke it, and examine the results.

Simple POST with Web Api .NET Core

The login controller is working fine, I tested it with Postman. The problem lies with the ajax call: it does not send the data as the body of the POST request but as URL query parameters (i.e. Username=username&Password=password).

To send the data in the body of the POST request you need to send the data as json string:

data: JSON.stringify({
"Username": "username",
"Password": "password"
}),

ASP.NET Web API post to an external api

A simple way to make HTTP-Request out of a .NET-Application is the System.Net.Http.HttpClient (MSDN). An example usage would look something like this:

// Should be a static readonly field/property, wich is only instanciated once
var client = new HttpClient();

var requestData = new Dictionary<string, string>
{
{ "field1", "Some data of the field" },
{ "field2", "Even more data" }
};

var request = new HttpRequestMessage() {
RequestUri = new Uri("https://domain.top/route"),
Method = HttpMethod.Post,
Content = new FormUrlEncodedContent(requestData)
};

request.Headers // Add or modify headers

var response = await client.SendAsync(request);

// To read the response as string
var responseString = await response.Content.ReadAsStringAsync();

// To read the response as json
var responseJson = await response.Content.ReadAsAsync<ResponseObject>();

C# Web API Sending Body Data in HTTP Post REST Client

Why are you generating you own json?

Use JSONConvert from JsonNewtonsoft.

Your json object string values need " " quotes and ,

I'd use http client for Posting, not webclient.

using (var client = new HttpClient())
{
var res = client.PostAsync("YOUR URL",
new StringContent(JsonConvert.SerializeObject(
new { OBJECT DEF HERE },
Encoding.UTF8, "application/json")
);

try
{
res.Result.EnsureSuccessStatusCode();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}

Not able to call simple web api post method from jquery

Well you are doing it wrong. There are 2 ways to achieve this.

  • 1st Method -

Add a model class StudentModel.cs

public class StudentModel
{
public string name { get; set; }
}

Then Accept that parameter as Model -

[Route("AddProduct")]
[HttpPost]
public string Add(StudentModel model)
{
return "";
}

and in Jquery Request ->

var postData = {};
postData.name = "Tom";
$("#Result").click(function () {
$.ajax({
url: '/api/Contact/AddProduct,
contentType: "application/json; charset=utf-8",
dataType: "json",
type: 'POST',
data: JSON.stringify(postData),
success: function (response) {
alert('hello');
},
failure: function (response) {
alert(response.responseText);
},
error: function (response) {
alert(response.responseText);
}
});
});
  • 2nd Method ->
    pass name as parameter in URl url: '/api/Contact/AddProduct?name=' + name and accept the paramter as string in Action AddProduct (Not Recommended as it is a POST request)

Return a simple integer value usign HTTPPOST method using .nep core web api

Just Add Routing on Controller

[Route("api/[controller]/[action]")]
[ApiController]
public class ValuesController : ControllerBase
{
[HttpPost("{value}")]
public int Pi(int value)
{
return value;
}
}

can only post to post method in asp.net core webapi

It is most likely because your controller doesn't understand difference between your routes. You need to define the routes explicitly like this:

[HttpPost("post")]
public string Post([FromBody] testclass t)
{
return "{\"a\":\"" + t.a + "\",\"b\":\"" + t.b + "\"}";
}

[HttpPost("test")]
public string Test([FromBody] testclass t)
{
return "{\"a\":\""+t.a+"\",\"b\":\""+t.b+"\"}";
}

And then post to them.

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

Sample Image

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);
});


Related Topics



Leave a reply



Submit