In my C# application I have a while loop that gathers a string from a Redis message queue and sends it to a listening server.
At every cicle the connection is opened with an HttpWebRequest Post method and the data is sent using a StreamWriter variable.
Problem is: after sending two strings the application freezes without returning any error, it just does nothing for maybe a minute, after that it works again correctly and continues its job for another couple strings, freeze and so on.
Debug shows the delay happens during the declaration of the StreamWriter variable.
Here is the core of the code:
// configure Redis
var redis = new RedisClient("127.0.0.1");
while (true)
{
// read from Redis queue
string json = redis.BRPop(30, "sensors_data");
//...
//URL DECLARATION
//...
try
{
var httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
httpWebRequest.ContentLength = json.Length;
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";
httpWebRequest.Proxy = null;
SendDataAsync(json, url);
}
}
static async Task SendDataAsync(string json, string url)
{
try
{
var httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
httpWebRequest.ContentLength = json.Length;
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";
httpWebRequest.Proxy = null;
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
try
{
streamWriter.Write(json);
streamWriter.Flush();
streamWriter.Close();
Console.Write("Data Sent");
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
}
catch (Exception err)
{
Console.Write(err.Message);
}
Console.WriteLine();
}
So the code actually works, just there is some strange huge delay where it comes to declare the StreamWriter. Does anyone have any idea? I don't know how to handle the problem.
EDIT
while (true)
{
i = 0;
// read from Redis queue
string json = redis.BRPop(30, "sensors_data");
try
{
var httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
httpWebRequest.ContentLength = json.Length;
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";
httpWebRequest.Proxy = null;
using (StreamWriter streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
try
{
streamWriter.Write(json);
streamWriter.Flush();
streamWriter.Close();
var response = httpWebRequest.GetResponse();
StreamReader reader = new StreamReader(response.GetResponseStream());
string reply=reader.ReadToEnd();
Console.WriteLine(reply);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
}
catch (Exception err)
{
Console.Write(err.Message);
}
Console.WriteLine();
}
Found the solution: Apparently it is necessary to get an answer from the server, after I added the httpWebRequest.GetResponse() and the following two lines I didn't find delays anymore.
Suggestion: it's better to use WebClient, it didn't give me any problem from the first try.
Related
I am working with web server to make calls to its API via HttpWebRequests. I wrote a standalone WPF application for testing purposes and all of my requests were functioning correctly. When I referenced the working project file in my production application it is now returning that the request is being actively refused by the server.
public string Post(string xmlData, Transaction transaction)
{
var result = "";
try
{
var webReq = (HttpWebRequest)WebRequest.Create(BaseUrl);
webReq.Accept = "application/xml";
webReq.ContentType = "application/xml";
webReq.Method = "POST";
webReq.KeepAlive = false;
webReq.Proxy = WebRequest.DefaultWebProxy;
webReq.ProtocolVersion = HttpVersion.Version10;
// If we passed in data to be written to the body of the request add it
if (!string.IsNullOrEmpty(xmlData))
{
webReq.ContentLength = xmlData.Length;
using (var streamWriter = new StreamWriter(webReq.GetRequestStream())) /**CONNECTION REFUSED EXCEPTION HERE**/
{
streamWriter.Write(xmlData);
streamWriter.Flush();
streamWriter.Close();
}
}
else //Otherwise write empty string as body
{
webReq.ContentLength = 0;
var data = "";
using (var streamWriter = new StreamWriter(webReq.GetRequestStream()))
{
streamWriter.Write(data);
streamWriter.Flush();
streamWriter.Close();
}
}
//Attempt to get response from web request, catch exception if there is one
using (var response = (HttpWebResponse)webReq.GetResponse())
{
using (var streamreader =
new StreamReader(response.GetResponseStream() ?? throw new InvalidOperationException()))
{
result = streamreader.ReadToEnd();
}
}
return result;
}
catch (WebException e)
{
//Handle web exceptions here
}
catch (Exception e)
{
//Handle other exceptions here
}
}
Has anyone else encountered this problem?
After reviewing your fiddler requests I can say that the reason is probably the IP address difference.
You use 192.168.1.186:44000 first time and 192.168.1.86:44000 second time.
I am attempting to create a console app that sends a WebRequest to a website so that I can get some information back from it in JSON format. Once I build up the request and try to get response I just want to simply print out the data, but when I call httpWebRequest.getResponse() it returns NULL.
I have tried multiple other methods of sending the data to the the url but those are all giving me like 404, or 400 errors, etc. This method at least isn't giving me any error, just a NULL.
Here is a snapshot of the documentation I am using for the API (albeit the docs aren't complete yet):
Here is the console app code that I have right now:
try
{
var httpWebRequest = (HttpWebRequest)WebRequest.Create("https://api.remot3.it/apv/v27/user/login");
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";
httpWebRequest.Headers.Add("developerkey", "***KEY***");
using (var streamWriter = new
StreamWriter(httpWebRequest.GetRequestStream()))
{
string json = new JavaScriptSerializer().Serialize(new
{
email = "***EMAIL***",
password = "***PASSWORD***"
});
Console.WriteLine(json);
streamWriter.Write(json);
}
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
Console.WriteLine(result);
Console.ReadLine();
}
}catch(Exception e)
{
Console.WriteLine(e.Message);
Console.WriteLine(e.StackTrace);
Console.ReadLine();
}
Expected output is some JSON data, but I am getting a NULL back from getResponse().
Try to serialize the credential in your form and for header send as parameter for this class.
Check below for my code. It is not 100 % fit to your requirement, but atleast it will help to get through your logic.
Here is what I get Json Response from this code. Its work Perfect. Please remember to add timeout option on your webrequest and at the end close the streamreader and stream after completing your task. please check this code.
public static string httpPost(string url, string json)
{
string content = "";
byte[] bs;
if (json != null && json != string.Empty)
{
bs = Encoding.UTF8.GetBytes(json);
}
else
{
bs = Encoding.UTF8.GetBytes(url);
}
HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(url);
req.Method = "POST";
if (json != string.Empty)
req.ContentType = "application/json";
else
req.ContentType = "application/x-www-form-urlencoded";
req.KeepAlive = false;
req.Timeout = 30000;
req.ReadWriteTimeout = 30000;
//req.UserAgent = "test.net";
req.Accept = "application/json";
req.ContentLength = bs.Length;
using (Stream reqStream = req.GetRequestStream())
{
reqStream.Write(bs, 0, bs.Length);
reqStream.Flush();
reqStream.Close();
}
using (WebResponse wr = req.GetResponse())
{
Stream s = wr.GetResponseStream();
StreamReader reader = new StreamReader(s, Encoding.UTF8);
content = reader.ReadToEnd();
wr.Close();
s.Close();
reader.Close();
}
return content;
}
I am doing an API Post request and cant seem to get it to work. I always get a sendFailure webexception and the response for the exception is always null so catching the exception is useless. It keeps happening when I try to get the httpWebResponse. I noticed too the request.contentlength gave errors at postream getrequeststream so i commented it out. Test.json is the file I use for the request body. I also tested this on different API testers by including the URL, body, and content-type in the header and they worked. I just cant seem to code it for myself. The credentials work I just dont know if im doing the request correctly?
JSON File:
{
"email": "abc#123.com",
"password": "12345",
"facilityNumber": "987654"
}
string filepath = "test.json";
string result = string.Empty;
using (StreamReader r = new StreamReader(filepath))
{
var json = r.ReadToEnd();
var jobj = JObject.Parse(json);
foreach (var item in jobj.Properties())
{
item.Value = item.Value.ToString().Replace("v1", "v2");
}
result = jobj.ToString();
Console.WriteLine(result);
}
try
{
string setupParameters;
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create("https://www.test.com/abcde");
request.AllowAutoRedirect = true;
setupParameters = result;
ServicePointManager.ServerCertificateValidationCallback = (s, cert, chain, ssl) => true;
ASCIIEncoding encoding = new ASCIIEncoding();
var postData = setupParameters;
request.Method = "POST";
request.ContentType = "application/json";
byte[] data = encoding.GetBytes(postData);
//request.ContentLength = data.Length;
using (StreamWriter postStream = new StreamWriter(request.GetRequestStream()))//error if uncomment contentlength
{
postStream.Write(postData);
postStream.Flush();
postStream.Close();
}
HttpWebResponse wr = (HttpWebResponse)request.GetResponse();//error occurs
Stream receiveStream = wr.GetResponseStream();
StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8);
}
catch (WebException ex)
{
if (ex.Response != null)
{
using (var errorResponse = (HttpWebResponse)ex.Response)
{
using (var reader = new StreamReader(errorResponse.GetResponseStream()))
{
string error = reader.ReadToEnd();
result = error;
}
}
}
I suggest modifiying your request to follow this format. Especially pay attention to the request.Method and request.ContentType which have caught me out multiple times.
Also, handling the response is easier this way.
try
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(YOURURL);
request.ContentType = "application/json; charset=utf8";
request.Headers.Add(ADD HEADER HERE IF YOU NEED ONE);
request.Method = WebRequestMethods.Http.Post; // IMPORTANT
using (var streamWriter = new StreamWriter(request.GetRequestStream()))
{
streamWriter.Write(JsonConvert.SerializeObject(JSONBODYSTRING));
// I USUALLY YOU JSONCONVERT HERE TO SIMPLY SERIALIZE A STRING CONTAINING THE JSON INFO.
//BUT I GUESS YOUR METHOD WOULD ALSO WORK
streamWriter.Flush();
streamWriter.Close();
}
WebResponse response = request.GetResponse();
using (var streamReader = new StreamReader(response.GetResponseStream()))
{
string result = streamReader.ReadToEnd();
// DO WHATEVER YOU'D LIKE HERE
}
} catch (Exception ex)
{
// HANDLE YOUR EXCEPTIONS
}
I have some problems with code. I'm using HttpWebRequest class to do operations
Code as bellow:
ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072 | (SecurityProtocolType)768;
ServicePointManager.Expect100Continue = true;
//ServicePointManager.DefaultConnectionLimit = 5;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(serverName + authorizePath);
request.Abort();
byte[] bearerMatch = UTF8Encoding.UTF8.GetBytes("username:password");
//request.Proxy = null; //<TNI_20180808
request.Method = "POST";
request.Accept = "application/json";
request.ContentType = "application/json";
request.Timeout = 100;
//request.Headers["Authorization"] = "Bearer " + Convert.ToBase64String(bearerMatch);
string content = String.Format(authorizeBody, login, password);
content = "{" + content + "}";
try
{
using (var writer = new StreamWriter(request.GetRequestStream()))
{
writer.Write(content);
}
using (WebResponse response = request.GetResponse())
{
using (var reader = new StreamReader(response.GetResponseStream()))
{
var responseContent = reader.ReadToEnd();
token = responseContent.Replace('"', ' ').Trim();
}
//response.Close();
//request.Abort();
}
}
catch (Exception ex)
{
throw ex;
}
Until third operation everything is okey, unfortunately i don't know what to do. When application is trying to create request third time there is an timeout error:
at System.Net.HttpWebRequest.GetRequestStream(TransportContext& context)
I think that there is an opportunity to solve this with closing request and response in a proper way but i don't know how to do this. After increasing ServicePointManager.DefaultConnectionLimit operations were getting completed correctly.
Can you help me please? How should i abort or close request/response in a good way?
Thank you!
I am developing application using .net MVC C#. I tried to call rest API of PayPal for save credit card details, my code were working fine but suddenly it starting through 400 Bad Request exception. here is my code,
private static async Task<string> StorePaymentCards(string accessToken, PaymentInfoModel cardDetails)
{
try
{
var httpWebRequest = (HttpWebRequest)WebRequest.Create("https://api.sandbox.paypal.com/v1/vault/credit-card");
var result = "";
httpWebRequest.ContentType = "application/json; charset=utf-8";
httpWebRequest.Method = "POST";
httpWebRequest.Accept = "application/json; charset=utf-8";
httpWebRequest.Headers.Add("Authorization", "Bearer " + accessToken);
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
var loginjson = new JavaScriptSerializer().Serialize(new
{
payer_id = cardDetails.PayerId.Trim(),
type = cardDetails.CardType.Trim(),
number = cardDetails.CardNumber.Trim(),
expire_month = cardDetails.ExpireMonth.Trim(),
expire_year = cardDetails.ExpireYear.Trim(),
first_name = cardDetails.FirstName.Trim()
});
streamWriter.Write(loginjson);
streamWriter.Flush();
streamWriter.Close();
//The code fails when creating the Response here, and go into catch block
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
result = streamReader.ReadToEnd();
}
return result;
}
}
catch (Exception ex)
{
return ex.GetBaseException().Message;
}
}
}
Can anyone help me out from this error?
Thank you in advance.
private static async Task<string> StorePaymentCards(string accessToken, PaymentInfoModel cardDetails)
{
try
{
//my stuff
}
catch (WebException ex)
{
string text = null;
using (WebResponse response = ex.Response)
{
HttpWebResponse httpResponse = (HttpWebResponse)response;
Console.WriteLine("Error code: {0}", httpResponse.StatusCode);
using (Stream data = response.GetResponseStream())
using (var reader = new StreamReader(data))
{
text = reader.ReadToEnd();
Console.WriteLine(text);
}
}
return text; //ex.GetBaseException().Message;
}
}
This is changed I have done in my catch block to trace proper error, so it return me that error which I was facing.