C#: Http Get behavior varies in different LAN - c#

I started an HTTP server in a local area network from C# as:
HttpListener listener = new HttpListener();
listener.Prefixes.Add(url);
listener.Start();
In another thread, it sends response as:
HttpListenerContext context = listener.GetContext();
context.Response.StatusCode = 200;
using (StreamWriter writer = new StreamWriter(context.Response.OutputStream)) {
writer.WriteLine(responseJson);
}
And in my client code, Http request is sent and processed as:
HttpClient client = new HttpClient();
HttpResponseMessage response = await client.GetAsync(url);
response.EnsureSuccessStatusCode();
string result = await response.Content.ReadAsStringAsync();
This server-client application works well in one LAN. But after I copied the application to another machine in another LAN, the last line of client code (await response result) got error " The input was not in a correct format". I really have no idea what it is about. I visited the server url from web browser, the correct response could be retrieved. So this is more likely to be a client-side issue, I guess.
Any help is appreciate.

Related

HTTP Request Failing in Production

My ASP.NET web app is interacting with an API and making calls to various endpoints.
When I hit the endpoints through Postman it's quick and successful. When I run the app locally it also works as expected. However, when I publish the app to Azure I'm having issues hitting the API and it's very inconsistent.
Sometimes it works and sometimes it doesn't. When it fails the call will hang up for a few seconds and then I get the following exception:
A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond
What I've come to notice through trial-and-error is that if I wait for around 10 seconds or so after each request it works. I tried using Thread.Sleep(10000) and Task.Delay(10000) to simulate me waiting the 10 seconds but those are causing issues (receiving the same connection attempt failed error).
using (HttpClient client = new HttpClient())
{
//Construct POST Request
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpRequestMessage req = new HttpRequestMessage(HttpMethod.Post, Global.api + "/token");
req.Content = new StringContent(body, Encoding.UTF8, "application/x-www-form-urlencoded");
//Do POST Request
using (HttpResponseMessage response = await client.SendAsync(req, HttpCompletionOption.ResponseContentRead))
{
using (HttpContent content = response.Content)
{
//Store data retrieved from POST request
string strContent = await content.ReadAsStringAsync();
Token token = await content.ReadAsAsync<Token>();
}
}
}
Thread.Sleep(10000);

Timeout while making POST request with no authentication C#

I want to make a POST request to a rest service. There is no authentication, it has only two customized header. My code is below. I am getting the error :
An exception of type 'System.AggregateException' occurred in mscorlib.dll but was not handled in user code.
"A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond"
May you help ? What is wrong in the code ?
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Add("id", "8888");
client.DefaultRequestHeaders.Add("type", "CUSTOMER");
Uri uri = new Uri(requestUri);
var ob = new { id= "5", color= "pink" };
var transferJson = JsonConvert.SerializeObject(ob);
var content = new StringContent(transferJson, Encoding.UTF8, "application/json");
HttpResponseMessage responseMessage = client.PostAsync(uri, content).Result;
Your code itself doesn't look faulty. The error message suggests that the request ran into a timout, which means that the HttpClient waits for a set period of time and terminates if the server doesn't respond. Have you tried pinging the server to make sure it's actually up and running?
It that's the case you could try to increase the timeout value of your HttpClient (see here https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.timeout?view=netframework-4.8).
Additionally you could try to send the request with another tool like Postman to see whether the issue lies within your code, your parameters (like timeout), or the server itself.

Cannot make C# HttpClient work reliably for long API response time

We need to talk to a third-party system through HTTP POST requests - depending on the parameters of such requests, it happens that processing time exceeds 5 minutes.
We have no issue fetching the data with CURL or Postman in such cases, but for some reason our HttpClient implementation hangs/remains stuck. Even creating an ad-hoc Console Application to talk to the server results in the following behavior:
Request starts -> Wait until whatever timeout we have set on HttpClient is triggered -> Tieout Exception. In other words, it appears that the response being sent by the server is "ignored" and the component waits for timeout. We are able to successfully make request from the same machine by using CURL or Postman, so I doubt it's machine-dependent.
Of course, the timeout is higher than the server response time, and we can confirm that the server is actually processing & sending the response through.
Size of the response payload does not change significantly with processing time - it seems that the only variable here is processing time itself.
Any clue / ideas for troubleshooting this?
Editing to add code (.NET 4.5):
var content = new StringContent("{}", Encoding.UTF8, "application/json");
client.Timeout = TimeSpan.FromMinutes(8);
var response = client.PostAsync("https://destination.service.com/myendpoint", content).Result;
var responseString = response.Content.ReadAsStringAsync().Result;
This is from a small testing C# Console Application that we created to troubleshoot the issue - really nothing too fancy as you can see.
I think the problem is that forcing an async call to be synchronous will block the thread during the process. The call will needs a thread to complete the operation, which will fails since no threads are available.
This is the case if called from UI Thread or from threadpool thread (a deadlock can also happens in main thread), especially when the workload is really high like yours.
Try the async version:
var response = await client.PostAsync("https://destination.service.com/myendpoint", content);
var responseString = await response.Content.ReadAsStringAsync();
check with async, like this:
private async Task<string> CallService()
{
HttpClient client = new HttpClient();
var content = new StringContent("{}", Encoding.UTF8, "application/json");
client.Timeout = TimeSpan.FromMinutes(8);
var response = await client.PostAsync(url, content);
string data = await response.Content.ReadAsStringAsync();
return data;
}
Can you edit your question to include the method signature of the console APP.
For me the signature and code should be changed to
public async Task<string> PostData()
{
var content = new StringContent("{}", Encoding.UTF8, "application/json");
client.Timeout = TimeSpan.FromMinutes(8);
var response = await client.PostAsync("https://destination.service.com/myendpoint", content);
var responseString = await response.Content.ReadAsStringAsync();
return responseString;
}

Need to call method as soon as server starts responding to my HttpWebRequest

I need to call a method in new thread for ex: mymethod() as soon as server starts responding to my HttpWebRequest.
I am using below to send http requst and getting response.
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(MyUrl);
HttpWebResponse response = (HttpWebResponse)request.GetResponse ();
Now what i need is for my request when server starts responding as soon as i need to call a method mymethod() in new thread. But problem is I don't know how to detect that server has started responding (started responsestream ) to my request.
What is the way that tell me that server started responding and I can call my method.
Target framework: is .net framework 4.5 and my project is Windows Form application.
The closest I can think of is using HttpClient and passing a HttpCompletionOption.ResponseHeadersRead, so you can start receiving the request once the headers are sent and later start processing the rest of the response:
public async Task ProcessRequestAsync()
{
var httpClient = new HttpClient();
var response = await httpClient.GetAsync(
url,
HttpCompletionOption.ResponseHeadersRead);
// When we reach this, only the headers have been read.
// Now, you can run your method
FooMethod();
// Continue reading the response. Change this to whichever
// output type you need (string, stream, etc..)
var content = response.Content.ReadAsStringAsync();
}

C# Windows Store App HTTPClient with Basic Authentication leads to 401 "Unauthorized"

I am trying to send a HTTP GET request to a service secured with BASIC authentication and https. If I use the RESTClient Firefox plugin to do so there is no problem. I am defining the basic-header and sending the GET to the url and I am getting the answer (data in json).
Now I am working on a Windows Store App in C# which is meant to consume the service. I enabled all required capabilities in the manifest and wrote the following method:
private async void HttpRequest()
{
string basic = "Basic ...........";
Uri testuri = new Uri(#"https://...Servlet");
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", basic);
Task<HttpResponseMessage> response = client.GetAsync(testuri);
var text = await response;
var message = text.RequestMessage;
}
I tried out many different possibilites like getting the response-string but everything lead to an 401 Status Code answer from the Server.
I looked at many similar problems and my understanding of the communication is the following: Client request -> Server response with 401 -> Client sends Authorization header -> Server response with 200 (OK)
What I don't understand is why I am getting the 401 "Unauthorized" Status Code although I am sending the Authorization header right at the beginning. It would be interesting if someone knows how this is handled in the RESTClient.
The BASIC header is definetly correct I was comparing it with the one in the RESTClient.
It would be great if someone could help me with this.
Thanks in advance and kind regards,
Max
Was having a similar problem, i added a HttpClientHandler to HttpClient.
var httpClientHandler = new HttpClientHandler();
httpClientHandler.Credentials = new System.Net.NetworkCredential("","")
var httpClient = new HttpClient(httpClientHandler);
Credentials should be encoded, before adding to the header. I tested it in WPF app, It works...
string _auth = string.Format("{0}:{1}", "username", "password");
string _enc = Convert.ToBase64String(Encoding.UTF8.GetBytes(_auth));
string _basic = string.Format("{0} {1}", "Basic", _enc);
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization",_basic);

Categories