0

I have an api

http://cbastest.cadvilpos.com/module/posmodule/customapi

with parameters

{
    "action":4,
    "device_token": "3e8ea119a90ee6d2",
    "key":"9475962085b3a1b8c475d52.95782804",
    "shop":1,
    "language":1
  }

This is working fine in postman. But when I try to connect from c# project its showing an error {"success":0,"error":"Missing the action parameter."}. Please give a working C# code to get the json result.

The code I tried:

var request = (HttpWebRequest)WebRequest.Create("http://cbastest.cadvilpos.com/module/posmodule/customapi");
var postData = "{ 'action':'4', 'device_token':'3e8ea119a90ee6d2','key':'9475962085b3a1b8c475d52.95782804','shop':'1','language':'1'}";
var data = Encoding.ASCII.GetBytes(postData);

request.Method = "POST";
request.ContentType = "application/json";
request.ContentLength = data.Length;

using (var stream = request.GetRequestStream())
{
    stream.Write(data, 0, data.Length);
}

var response2 = (HttpWebResponse)request.GetResponse();
var responseString = new StreamReader(response2.GetResponseStream()).ReadToEnd();
Panagiotis Kanavos
  • 120,703
  • 13
  • 188
  • 236
TechDo
  • 18,398
  • 3
  • 51
  • 64
  • Can you share us how is the code of your C# Action? – Matheus Cuba Jul 03 '18 at 13:31
  • Possible duplicate of [POSTing JsonObject With HttpClient From Web API](https://stackoverflow.com/questions/6117101/posting-jsonobject-with-httpclient-from-web-api) – Panagiotis Kanavos Jul 03 '18 at 13:40
  • You *don't* need to use a raw HttpWebRequest object to make an HTTP call. Check the duplicate, it only takes 2 lines to call `var content=new StringContent(postData,Encoding.UTF8, "application/json");var response=await httpClient.PostAsync(url,content);`. 3 lines if you *don't* construct the JSON string by hand but use eg JSON.NET to serialize a strongly typed object. – Panagiotis Kanavos Jul 03 '18 at 13:43
  • And only one line if you use the `PostAsJsonAsync` extension method found in [Microsoft.AspNet.WebApi.Client](https://www.nuget.org/packages/Microsoft.AspNet.WebApi.Client/). Never mind the name, the package adds formatting methods on top of HttpClient. It's not specific to ASP.NET Web API – Panagiotis Kanavos Jul 03 '18 at 13:47

2 Answers2

2

You don't need to use a raw HttpWebRequest object to make an HTTP call. HttpClient was introduced in 2012 to allow easy asynchronous HTTP calls.

You could do something as simple as :

var content=new StringContent(postData,Encoding.UTF8, "application/json");
HttpResponseMessage response=await httpClient.PostAsync(url,content);
//Now process the response
if (response.IsSuccessCode)
{
   var body=await response.Content.ReadAsStringAsync();
   var responseDTO=JsonConvert.DeserializeObject<MyDTO>(body);
}

Instead of building a JSON string by hand you could use a strongly typed class or an anonymous object and serialize it to JSON with JSON.NET :

var data=new {
    action=4,
    device_token="3e8ea119a90ee6d2",
    key = "9475962085b3a1b8c475d52.95782804",
    shop=1,
    language=1
};

var postData=JsonConvert.SerializeObject(data);
var content=new StringContent(postData,Encoding.UTF8, "application/json");
var response=await httpClient.PostAsync(url,content);
...

You can read a response body in one go as a string, using ReadAsStringAsync or you can get the response stream with ReadAsStreamAsync. You could copy the response data directly to another stream, eg a file or memory stream with HttpContent.CopyToAsync

Check Call a Web API from a .NET Client for more examples. Despite the title, the examples work to call any HTTP/REST API.

The Microsoft.AspNet.WebApi.Client package mentioned in that article is another thing that applies to any call, not just calls to ASP.NET Web API. The extension method PostAsJsonAsync for example, combines serializing and posting a request to a url. Using it, posting the action DTO could be reduced to a single line:

var data=new {
    action=4,
    device_token="3e8ea119a90ee6d2",
    key = "9475962085b3a1b8c475d52.95782804",
    shop=1,
    language=1
};

var response=await httpClient.PostAsJsonAsync(url,data);
Panagiotis Kanavos
  • 120,703
  • 13
  • 188
  • 236
  • 1
    There are a lot of goodies in HttpClient. If you use .NET Core you'll find it contains a *lot* of performance and reliability enhancements. Check Scott Hanselman's [articles](https://www.hanselman.com/blog/HttpClientFactoryForTypedHttpClientInstancesInASPNETCore21.aspx) on the new features – Panagiotis Kanavos Jul 03 '18 at 14:09
1

There is a button in Postman that will generate code for the currently defined request. The link is here: enter image description here

And this is what the code looks like. You'll need to pull in RestSharp from Nuget enter image description here

Josh
  • 4,009
  • 2
  • 31
  • 46
  • THere's no need to use RestClient when .NET already contains HttpClient – Panagiotis Kanavos Jul 03 '18 at 13:48
  • Yeah, you can use HttpClient or the raw socket class to do it. I use this flow when I'm back and forth with Postman shaping the request. Adding a Nuget package isn't a big deal, as you showed above by leveraging Microsoft.AspNet.WebApi.Client – Josh Jul 03 '18 at 14:18
  • The difference is asynchronous execution and thread safety. That is a very big deal - the less you block, the less you spinwait, the less CPU you use ==> you need fewer servers for the same load. Since you mentioned sockets, HttpClient in .NET Core 2.1 got a new SocketsHttpClientHandler that reduces allocations by using Span and Pipelines. The result is a huge performance and memory improvement. – Panagiotis Kanavos Jul 03 '18 at 14:24
  • RestSharp offers async methods. Thread blocking doesn't consume CPU. Async/await is very useful and should be used by default when load is a concern but nothing is free, and not every situation requires it – Josh Jul 03 '18 at 14:40