Setting ContentLength on HttpWebRequest gives me a timeout error - c#

I am creating an android app that connects to my website's api using C# and xamarin. After debugging for a while I realised that when I set the ContentLength the apps seams to hang and then throws an TIMEOUT exception.
I have tried to not set the ContentLength but then the body seams to not send with the request.
public void Post(object data, string route){
string JSON = JsonConvert.SerializeObject(data);
var web = (HttpWebRequest)WebRequest.Create("http://httpbin.org/post");
//web.ContentLenfth = JSON.length;
web.ContentType = "application/json";
web.Method = "POST";
try{
var sw = new StreamWriter(webRequest.GetRequestStream());
sw.Write(JSON);
var webResponse = (HttpWebResponse)webRequest.GetResponse();
var sr = new StreamReader(webResponse.GetResponseStream());
var result = sr.ReadToEnd();
...
}
...
}
If ContentLengt is set the app hangs until the timeout function is called
else the test-url I am posting to tells me that I did not send a body
What do I have to do in order to send a successful POST request ?

You should set the length to be the length of the byte array you are sending (not the length of the string)
You can get the byte array from the json string by doing:
var bytes = Encoding.UTF8.GetBytes(JSON);
Then you can set the content length:
web.ContentLength = bytes.length;
And send the bytes:
using (var requestStream = web.GetRequestStream())
{
requestStream.Write(bytes, 0, bytes.Length);
}

Related

C#: Make new api calls to get new responses

I'm using text generation API and I want to generate a new response each time, which was not the case in my side.
class Program
{
static void Main(string[] args)
{
//make a request to URI
var request = (HttpWebRequest)WebRequest.Create("https://api-inference.huggingface.co/models/gpt2");
//Input data
var postData = "My name is Thomas and my main";
//encoding the input to type byte
var data = Encoding.ASCII.GetBytes(postData);
//send a POST request to the api
request.Method = "POST";
// Set the content length of the string being posted
using (var stream = request.GetRequestStream())
{
stream.Write(data, 0, data.Length);
}
// get the stream of the request
var response = (HttpWebResponse)request.GetResponse();
//Print the generated text of "generated-text"
var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
Console.Write(responseString);
}
}
So as far as I understood the call is getting cached.
How can I stop this from happening ? So that I get a new response each time I call the api

WEB API C# REPONSE HANGS (HttpWebResponse)http.GetResponse()

Am doing an WEB API .net 4.62 that /Token with username password and grant_type to get access token once its generated i woul like to get it value of access_token.This does not happen but when i take the same code to a windows form aplication I am able to get it what could be wrong. It hangs on using (HttpWebResponse response = (HttpWebResponse)http.GetResponse())
try
{
string myParameters = "username=value1&password=value2&grant_type=password";
string baseAddress = "http://localhost:50128/token";
var http = (HttpWebRequest)WebRequest.Create(new Uri(baseAddress));
http.Accept = "application/x-www-form-urlencoded";
http.ContentType = "application/x-www-form-urlencoded";
http.Method = "POST";
string parsedContent = myParameters;
ASCIIEncoding encoding = new ASCIIEncoding();
Byte[] bytes = encoding.GetBytes(parsedContent);
Stream newStream = http.GetRequestStream();
newStream.Write(bytes, 0, bytes.Length);
newStream.Close();
http.ServicePoint.Expect100Continue = false;
http.ProtocolVersion = HttpVersion.Version11;
http.Timeout = 2000;
using (HttpWebResponse response = (HttpWebResponse)http.GetResponse())
{
var stream = response.GetResponseStream();
var sr = new StreamReader(stream);
var content = sr.ReadToEnd();
JObject json = JObject.Parse(content);
var message = json.SelectToken("access_token").ToString();
Console.Write(message);
}
}
catch (Exception ex)
{
//Handle the exceptions that could appear
}
change the using block like this and also convert your function to "async".
using (HttpWebResponse response = (HttpWebResponse)await Task.Factory.FromAsync(http.BeginGetResponse, http.EndGetResponse, null).ConfigureAwait(false))
let me know if it works.

using OpenTSDB HTTP api in .NET : 400 Bad Request

I'm trying to use .net to put datapoints in OpenTSDB, using the HTTP /api/put API.
I've tried with httpclient, webRequest and HttpWebRequest. The outcome is always 400 - bad request: chunked request not supported.
I've tried my payload with an api tester (DHC) and works well.
I've tried to send a very small payload (even plain wrong, like "x") but the reply is always the same.
Here's one of my code instances:
public async static Task PutAsync(DataPoint dataPoint)
{
try
{
HttpWebRequest http = (HttpWebRequest)WebRequest.Create("http://127.0.0.1:4242/api/put");
http.SendChunked = false;
http.Method = "POST";
http.ContentType = "application/json";
Encoding encoder = Encoding.UTF8;
byte[] data = encoder.GetBytes( dataPoint.ToJson() + Environment.NewLine);
http.Method = "POST";
http.ContentType = "application/json; charset=utf-8";
http.ContentLength = data.Length;
using (Stream stream = http.GetRequestStream())
{
stream.Write(data, 0, data.Length);
stream.Close();
}
WebResponse response = http.GetResponse();
var streamOutput = response.GetResponseStream();
StreamReader sr = new StreamReader(streamOutput);
string content = sr.ReadToEnd();
Console.WriteLine(content);
}
catch (WebException exc)
{
StreamReader reader = new StreamReader(exc.Response.GetResponseStream());
var content = reader.ReadToEnd();
}
return ;
}
where I explicitly set to false the SendChunked property.
note that other requests, like:
public static async Task<bool> Connect(Uri uri)
{
HttpWebRequest http = (HttpWebRequest)WebRequest.Create("http://127.0.0.1:4242/api/version");
http.SendChunked = false;
http.Method = "GET";
// http.Headers.Clear();
//http.Headers.Add("Content-Type", "application/json");
http.ContentType = "application/json";
WebResponse response = http.GetResponse();
var stream = response.GetResponseStream();
StreamReader sr = new StreamReader(stream);
string content = sr.ReadToEnd();
Console.WriteLine(content);
return true;
}
work flawlessly.
I am sure I am doing something really wrong.
I'd like to to reimplement HTTP in Sockets from scratch.
I've found a solution I'd like to share here.
I've used wireshark to sniff my packets, and I've found that this header is added:
Expect: 100-continue\r\n
(see 8.2.3 of https://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html)
This is the culprit. I've read the post http://haacked.com/archive/2004/05/15/http-web-request-expect-100-continue.aspx/ by Phil Haack, and found that HttpWebRequest puts that header by default, unless you tell it to stop. In this article I've found that using ServicePointManager I can do just this.
Putting the following code on top of my method, when declaring the http object, makes it work very well, and solves my issue:
var uri = new Uri("http://127.0.0.1:4242/api/put");
var spm = ServicePointManager.FindServicePoint(uri);
spm.Expect100Continue = false;
HttpWebRequest http = (HttpWebRequest)WebRequest.Create(uri);
http.SendChunked = false;

Take Delay on HttpWebRequest.GetRequestStream

I am using HttpWebRequest.GetRequestStream to connect on the other PHP link from Dot Net to POST some data from .Net to PHP. But its worked fine the first two times when the control come to the line "Stream newrStream = myrRequest.GetRequestStream();" and taking delay for some second from third time onwards.How to slove this problem.
My coding is:
ASCIIEncoding Encode = new ASCIIEncoding();
string postDat = "Name=xxx";
byte[] datas = Encode.GetBytes(postDat);
HttpWebRequest myrRequest = HttpWebRequest)WebRequest.Create("http://www.xxx.php");
myrRequest.Method = "POST";
myrRequest.ContentType = "application/x-www-form-urlencoded";
myrRequest.ContentLength = datas.Length;
Stream newrStream = myrRequest.GetRequestStream();
// Send the data.
newrStream.Write(datas, 0, datas.Length);
newrStream.Close();
The first thing to keep in mind is to review the URI, parameters and headers being sent, specifically:
Reserved characters. Send reserved characters by the URI can bring
problems ! * ' ( ) ; : # & = + $ , / ? # [ ]
URI Length: You should not exceed 2000 characters
Length headers:Most web servers do limit size of headers they
accept. For example in Apache default limit is 8KB.
Keep in mind that if you want to send data from a longer length is recommended to send in the body of the message:
string uri = string.Format("https://my-server.com/api/document?queryParameter={1}", "value");
WebRequest req = WebRequest.Create(uri);
req.Method = "POST";
string data = "Some data"; //Body data
ServicePointManager.Expect100Continue = false;
using (var streamWriter = new StreamWriter(req.GetRequestStream()))
{
streamWriter.Write(data);
streamWriter.Flush();
streamWriter.Close();
}
HttpWebResponse resp = req.GetResponse() as HttpWebResponse;
Stream GETResponseStream = resp.GetResponseStream();
StreamReader sr = new StreamReader(GETResponseStream);
var response = sr.ReadToEnd(); //Response
resp.Close(); //Close response
sr.Close(); //Close StreamReader

How to use WebRequest to POST some data and read response?

Need to have the server make a POST to an API, how do I add POST values to a WebRequest object and how do I send it and get the response (it will be a string) out?
I need to POST TWO values, and sometimes more, I see in these examples where it says string postData = "a string to post"; but how do I let the thing I am POSTing to know that there is multiple form values?
From MSDN
// Create a request using a URL that can receive a post.
WebRequest request = WebRequest.Create ("http://contoso.com/PostAccepter.aspx ");
// Set the Method property of the request to POST.
request.Method = "POST";
// Create POST data and convert it to a byte array.
string postData = "This is a test that posts this string to a Web server.";
byte[] byteArray = Encoding.UTF8.GetBytes (postData);
// Set the ContentType property of the WebRequest.
request.ContentType = "application/x-www-form-urlencoded";
// Set the ContentLength property of the WebRequest.
request.ContentLength = byteArray.Length;
// Get the request stream.
Stream dataStream = request.GetRequestStream ();
// Write the data to the request stream.
dataStream.Write (byteArray, 0, byteArray.Length);
// Close the Stream object.
dataStream.Close ();
// Get the response.
WebResponse response = request.GetResponse ();
// Display the status.
Console.WriteLine (((HttpWebResponse)response).StatusDescription);
// Get the stream containing content returned by the server.
dataStream = response.GetResponseStream ();
// Open the stream using a StreamReader for easy access.
StreamReader reader = new StreamReader (dataStream);
// Read the content.
string responseFromServer = reader.ReadToEnd ();
// Display the content.
Console.WriteLine (responseFromServer);
// Clean up the streams.
reader.Close ();
dataStream.Close ();
response.Close ();
Take into account that the information must be sent in the format key1=value1&key2=value2
Here's what works for me. I'm sure it can be improved, so feel free to make suggestions or edit to make it better.
const string WEBSERVICE_URL = "http://localhost/projectname/ServiceName.svc/ServiceMethod";
//This string is untested, but I think it's ok.
string jsonData = "{ \"key1\" : \"value1\", \"key2\":\"value2\" }";
try
{
var webRequest = System.Net.WebRequest.Create(WEBSERVICE_URL);
if (webRequest != null)
{
webRequest.Method = "POST";
webRequest.Timeout = 20000;
webRequest.ContentType = "application/json";
using (System.IO.Stream s = webRequest.GetRequestStream())
{
using (System.IO.StreamWriter sw = new System.IO.StreamWriter(s))
sw.Write(jsonData);
}
using (System.IO.Stream s = webRequest.GetResponse().GetResponseStream())
{
using (System.IO.StreamReader sr = new System.IO.StreamReader(s))
{
var jsonResponse = sr.ReadToEnd();
System.Diagnostics.Debug.WriteLine(String.Format("Response: {0}", jsonResponse));
}
}
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.ToString());
}
Here's an example of posting to a web service using the HttpWebRequest and HttpWebResponse objects.
StringBuilder sb = new StringBuilder();
string query = "?q=" + latitude + "%2C" + longitude + "&format=xml&key=xxxxxxxxxxxxxxxxxxxxxxxx";
string weatherservice = "http://api.worldweatheronline.com/free/v1/marine.ashx" + query;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(weatherservice);
request.Referer = "http://www.yourdomain.com";
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream stream = response.GetResponseStream();
StreamReader reader = new StreamReader(stream);
Char[] readBuffer = new Char[256];
int count = reader.Read(readBuffer, 0, 256);
while (count > 0)
{
String output = new String(readBuffer, 0, count);
sb.Append(output);
count = reader.Read(readBuffer, 0, 256);
}
string xml = sb.ToString();
A more powerful and flexible example can be found here: C# File Upload with form fields, cookies and headers
Below is the code that read the data from the text file and sends it to the handler for processing and receive the response data from the handler and read it and store the data in the string builder class
//Get the data from text file that needs to be sent.
FileStream fileStream = new FileStream(#"G:\Papertest.txt", FileMode.OpenOrCreate, FileAccess.ReadWrite);
byte[] buffer = new byte[fileStream.Length];
int count = fileStream.Read(buffer, 0, buffer.Length);
//This is a handler would recieve the data and process it and sends back response.
WebRequest myWebRequest = WebRequest.Create(#"http://localhost/Provider/ProcessorHandler.ashx");
myWebRequest.ContentLength = buffer.Length;
myWebRequest.ContentType = "application/octet-stream";
myWebRequest.Method = "POST";
// get the stream object that holds request stream.
Stream stream = myWebRequest.GetRequestStream();
stream.Write(buffer, 0, buffer.Length);
stream.Close();
//Sends a web request and wait for response.
try
{
WebResponse webResponse = myWebRequest.GetResponse();
//get Stream Data from the response
Stream respData = webResponse.GetResponseStream();
//read the response from stream.
StreamReader streamReader = new StreamReader(respData);
string name;
StringBuilder str = new StringBuilder();
while ((name = streamReader.ReadLine()) != null)
{
str.Append(name); // Add to stringbuider when response contains multple lines data
}
}
catch (Exception ex)
{
throw ex;
}

Categories

Resources