Asynchronous web Post API call from c# - c#

I am writing the code as :
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(qry);
request.ContentType = "application/x-www-form-urlencoded";
request.Method = "POST";
request.KeepAlive = false;
request.ContentLength = 0;
byte[] data = Encoding.UTF8.GetBytes(crsAdapterXML.ToString());
request.ContentLength = data.Length;
Stream stream = request.GetRequestStream();
stream.Write(data, 0, data.Length);
stream.Close();
Stream objStream = request.GetResponse().GetResponseStream();
StreamReader objReader = new StreamReader(objStream);
result = Convert.ToString(objReader.ReadLine());
I need to make this call asyncronous. Can anyone help me with this.

Using HttpWebRequest is kinda old school way of doing HTTP requests nowadays.
There are libraries which provide better APIs to do this.
I recommend you to try Microsoft's HttpClient (System.Net.Http) or RestSharp.
There are probably many more but those are the ones I know and didn't have problems with.
Both provide async API so you can asynchronously wait for a response.
I don't have much experience with HttpWebRequest but it seems it also exposes async variations of its methods like GetResponseAsync or GetRequestStreamAsync

Related

HttpWebRequest returns (400) Bad Request

The request gives the following error:
The remote server returned an error: (400) Bad Request.
I cann't find a solution on internet. Does anyone knows how to solve this?
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(#"https://maps.googleapis.com/maps/api/geocode/json");
request.ContentType = "application/x-www-form-urlencoded";
request.Method = "POST";
var parameters = string.Format("language={0}&latlng={1}&client={2}&signature={3}", "nl", "51.123456,5.612345", "gme-aa", "******_******=");
byte[] byteArray = Encoding.UTF8.GetBytes(parameters);
request.ContentLength = byteArray.Length;
Stream dataStream = request.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();
/*
* Read HttpWeb Response
*/
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
dataStream = response.GetResponseStream();
StreamReader reader = new StreamReader(dataStream);
string Response = reader.ReadToEnd();
response.Close();
EDIT:
I'm working inside Lowcode platform Outsystems. Outsystems creates the url inside WebRequest.Create() without the paramaters. So, I have access to webRequest object and need to pass the parameters.
You have to use HTTP "GET" Method.
In a GET request, you pass parameters as part of the query string.
HttpWebRequest request = (HttpWebRequest)WebRequest.Create($"https://maps.googleapis.com/maps/api/geocode/json?language=fr&latlng=51.123456,5.612345&key={apiKey}");
request.ContentType = "application/x-www-form-urlencoded";
request.Method = "GET";
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
string result = new StreamReader(response.GetResponseStream()).ReadToEnd();
}
According the documentation, the API is expecting a POST method and receiving the parameters in the URL and not the body.
If you are using the OutSystems platform you can use the Consume REST API functionality to easily call the web service without using code. Configure your API like this (you can copy the example JSON from the documentation page above):

web request in asp.net core

I want to do a web request in a asp.net core project. I tried the following but it doesn't seem to send the data in the request:
using System.Net;
...
//encoder
UTF8Encoding enc = new UTF8Encoding();
//data
string data = "[\"some.data\"]";
//Create request
WebRequest request = WebRequest.Create(url);
request.Method = "POST";
request.ContentType = "application/json";
request.Credentials = new NetworkCredential(user, secret);
//Set data in request
Stream dataStream = await request.GetRequestStreamAsync();
dataStream.Write(enc.GetBytes(data), 0, data.Length);
//Get the response
WebResponse wr = await request.GetResponseAsync();
Stream receiveStream = wr.GetResponseStream();
StreamReader reader = new StreamReader(receiveStream, Encoding.UTF8);
string content = reader.ReadToEnd();
I don't get an error, the request was send but it doesn't seem to send the data with the request.
I also can't give the length of the data with the request. Is this a core issue? (ps: The credentials are send correctly)
Can anyone help me?
You may be facing a synchronization context problem.
Try to await the asynchronous methods like GetRequestStreamAsync() and GetResponseAsync() instead of getting the Result property.
//Set data in request
Stream dataStream = await request.GetRequestStreamAsync();
//Get the response
WebResponse wr = await request.GetResponseAsync();
Finally solved it. There was a bug in my external API code where I resolved the API request. The code in my question works (If someone wants to use it).
PS: I edit the code with the remark of ycrumeyrolle

Send and receive Json, cant read the response

I'm creating a application, and in one of it's functionalities I need to send json code over web request.
I use Get, Post, Put and Delete. And I already can create the connection and send and receive data.
But, for every request I should receive json code. Which I believe I am receiving, but I can't read it...
I'l put some code sample so you can see if there is something I can make to read that json code
First the Get request:
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create (this.getURL ());
webRequest.Method = "GET";
webRequest.ContentType = "application/json";
webRequest.Accept = "application/json";
var response = (HttpWebResponse)webRequest.GetResponse ();
var responseString = new StreamReader (response.GetResponseStream ()).ReadToEnd ();
webRequest.Abort();
return JArray.Parse (responseString);
This is the only case where I can read the json answer.
Next Post request:
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create (this.getURL ());
webRequest.Method = "POST";
webRequest.ContentType = "application/json";
webRequest.Accept = "application/json";
var data = Encoding.UTF8.GetBytes(request);
webRequest.ContentLength = data.Length;
Stream stream = webRequest.GetRequestStream ();
stream.Write (data, 0, data.Length);
stream.Close ();
var response = (HttpWebResponse)webRequest.GetResponse();
webRequest.Abort();
return (int)response.StatusCode;
In this example I solved my problem using the response code.. which can only be 200, because every other code Is assumed as some exception.
For put and delete will be the same as post.
As I said I need to receive the json code. and not only the response code.
I would be really grateful if you could help-me in this problem.
Thanks to Orel who tried do help.
I got mt problem solved, I will post a sample code for everyone who might need this kind of solution.
My problem actually was very simple.
When I used "POST" in a web request I would create a stream to actually post my data. And then I would try to get my answer from that same stream, when actually I was getting the information I needed In the webRequest var.
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create (this.getURL ());
webRequest.Method = "POST";
webRequest.ContentType = "application/json";
webRequest.Accept = "application/json";
var data = Encoding.UTF8.GetBytes(request);
webRequest.ContentLength = data.Length;
Stream stream = webRequest.GetRequestStream ();
stream.Write (data, 0, data.Length);
var webResponse = (HttpWebResponse)webRequest.GetResponse();
var responseString = new StreamReader(webResponse.GetResponseStream()).ReadToEnd();
stream.Close ();webRequest.Abort();
return JObject.Parse(responseString);

WebRequest.GetRequestStreamAsync() method timesout each time for MNS access token

I am trying to get the access token from MNS for Push notifications and the WebRequest.GetRequestStreamAsync() method timesout each time. Any suggestions?
Reference: http://msdn.microsoft.com/en-us/library/windows/apps/hh913756.aspx
Below is the code I use
HttpWebRequest webRequest = (HttpWebRequest)HttpWebRequest.Create("https://login.live.com/accesstoken.srf");
webRequest.Method = "POST";
webRequest.ContentType = "application/x-www-form-urlencoded";
string postString = String.Format("grant_type=client_credentials&client_id={0}&client_secret={1}&scope=notify.windows.com",
SID,
SECRET_KEY);
byte[] data = Encoding.UTF8.GetBytes(postString);
Stream newStream = await webRequest.GetRequestStreamAsync();
newStream.Write(data, 0, data.Length);
Try rewriting it like this and see if it makes a difference. I've sometimes had problems with HttpWebRequest where WebRequest worked fine. Also make sure you close your streams.
WebRequest webRequest = WebRequest.Create("https://login.live.com/accesstoken.srf");
webRequest.Method = "POST";
webRequest.ContentType = "application/x-www-form-urlencoded";
string postString = String.Format("grant_type=client_credentials&client_id={0}&client_secret={1}&scope=notify.windows.com",
SID,
SECRET_KEY);
byte[] data = Encoding.UTF8.GetBytes(postString);
Stream newStream = await webRequest.GetRequestStreamAsync();
newStream.Write(data, 0, data.Length);
newStream.Close();
WebResponse response = webRequest.GetResponse();
StreamReader requestReader = new StreamReader( response.GetResponseStream() );
string webResponse = requestReader.ReadToEnd();
response.Close();
Call .ConfigureAwait(false) on your Async method.
This blog post should explain the why and how.
We had the same problem and it turned out to be a problem in different place than one would originally guess.
You need to .Dispose() or at least .Close() the response that you get from .GetResponseAsync, otherwise the next call to .GetRequestStreamAsync hangs.
It seems that the code behind this holds some limited (rather low) amount of sockets or locks, that disallow further requests to even begin until previous request has completed.

Using REST PUT in C#

I am working with a REST API and I am trying to do a PUT method to it. I found this code I was going to give a try:
static void Main()
{
string xml = "<xml>...</xml>";
byte[] arr = System.Text.Encoding.UTF8.GetBytes(xml);
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create("http://localhost/");
request.Method = "PUT";
request.ContentType = "text/xml";
request.ContentLength = arr.Length;
Stream dataStream = request.GetRequestStream();
dataStream.Write(arr, 0, arr.Length);
dataStream.Close();
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
string returnString = response.StatusCode.ToString();
Console.WriteLine(returnString);
}
One thing I want to do if possible, and can't seem to find anything about it. I would like to pass the data of text fields so, txtEmail.Text, txtFirstName.Text, etc. Is this possible? If, so how would I go about doing this? Does this code look like it would work? Unfortunately the API I'm working with has very very little documentation. Thanks!
The code lines
Stream dataStream = request.GetRequestStream();
dataStream.Write(arr, 0, arr.Length);
dataStream.Close();
do write something to the remote website. The request stream is the way to provide data to the server, so you would create a string / object that you write to the stream to transfer to the server. In your example <xml>...</xml> is sent to the server.

Categories

Resources