C# WebRequest timeout on second call - c#

The first time I call this function everything works perfect.
When I call it the second time I get an exception Host is not responding correclty
I tried everything for hours but I dont get it to work.
Is it the website or is something wrong with my code?
string url = "https://www.nseindia.com/live_market/dynaContent/live_watch/option_chain/optionKeys.jsp";
string website = "";
HttpWebRequest httpRequest = (HttpWebRequest)WebRequest.Create(url);
httpRequest.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
httpRequest.Timeout = 5000;
using (var response = (HttpWebResponse)httpRequest.GetResponse())
{
using (StreamReader Reader = new StreamReader(response.GetResponseStream()))
{
website = Reader.ReadToEnd();
}
}
httpRequest.Abort();

Please, on every question that you are going to do here, try to put as maximum of details as possible. It will become easier for us to help you on your problems. Especially the exceptions that you are having doing the development.
About your code, the implementation of that is not recommended for Microsoft. Looking at the docs https://learn.microsoft.com/en-us/dotnet/api/system.net.httpwebrequest?view=netframework-4.8 there is a part that says: We don't recommend that you use HttpWebRequest for new development. Instead, use the System.Net.Http.HttpClient class.
Try to change your implementation to use the class HttpClient, and see if the error is going to occur again.

Related

"The request was aborted: Could not create SSL/TLS secure channel" in HttpWebRequest, even after specifying ServicePointManager.SecurityProtocol

In order to meet PCI compliance, we have had to completely disable TLS 1.0 from our servers. Ever since doing this, I have had to specify which protocol to use when making web requests in order for things to work. However, one particular problem persists. Even when I specify the protocol, I still get the error stated in the title.
var httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";
httpWebRequest.KeepAlive = false;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11;
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
streamWriter.Write(body);
}
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
return result;
}
The error itself is generated from the line -
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
As you can see, I am specifying to use either TLS 1.1 or 1.2 (I originally had it at 1.2 only, but thought allowing 1.1 as well would help, but it did not).
Additionally (not sure if this is pertinent or not), this particular snippet of code is always calling an API that we also run and maintain, so essentially, the server is calling itself to get a piece of info it needs.
And I am fast running out of ideas on what I can try to further debug or fix this, so any help out there would be greatly appreciated.
I finally figured this one out, and the solution is far simpler than I'd like to admit. I simply moved the line
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11;
to the very top of the code snippet I posted in the question, and everything has been working since. I'm guessing it needs to be in place before creating the HttpWebRequest?

C# HttpWebRequest vs browser

I'm trying to integrate with Shopping.com REST service.
so I wrote a simple (minimum code) C# application to retrieve the XML data using HttpWebRequest class. I've used StopWatch for bench-marking and the response time (Including Stream.ReadToEnd()) is something like 1300-1700 milliseconds.
it might sound good, but then I've tested the response time in Chrome browser with Fiddler and the response time was about 600-800.
I've read few articles. some suggested set HttpWebRequest.Proxy to null / WebRequest.DefaultWebProxy but it didn't make significant improvement.
Here the request-url:
http://sandbox.api.shopping.com/publisher/3.0/rest/GeneralSearch?apiKey=78b0db8a-0ee1-4939-a2f9-d3cd95ec0fcc&trackingId=7000610&keyword=nikon
So, what should I do to reach this response time?
Are you enabling gzip and deflate?
Also, the first time you execute a web request in your code, there is a warmup to load the necessary assemblies, initialize the service point, and establish the HTTP connection, so be sure to look at the time for the second and subsequent executions.
EDIT: Sorry you will still need to decode the results using a GZipStream or DeflateStream, but this at least gives you the idea. See here for more info: HttpWebRequest & Native GZip Compression
var timer = Stopwatch.StartNew();
var url = "http://sandbox.api.shopping.com/publisher/3.0/rest/GeneralSearch?apiKey=78b0db8a-0ee1-4939-a2f9-d3cd95ec0fcc&trackingId=7000610&keyword=nikon";
var webRequest = WebRequest.Create(url);
webRequest.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip, deflate");
using (var webResponse = webRequest.GetResponse())
using (var responseStream = webResponse.GetResponseStream())
using (var streamReader = new StreamReader(responseStream))
{
var content = streamReader.ReadToEnd();
}
var timeSpan = timer.Elapsed;
Console.WriteLine(timeSpan);

Call to REST web service results in response of error 503 but not with a tool like Poster

I am trying to send an xml document to a REST web service. Using a tool like Poster, the call works fine (With the xml in the body of the "content"), but in my code, I get error 503 server unavailable.
Link to Poster: https://addons.mozilla.org/en-US/firefox/addon/poster/
My code is as follows (this is a test-harness so no error handling etc):
string s = "";
using (StreamReader sr = new StreamReader(#"c:\users\dev.admin\documents\visual studio 2010\Projects\WindowsFormsApplication2\WindowsFormsApplication2\XMLFile1.xml"))
{
s = sr.ReadToEnd();
}
string url = FULL_URL_WITH_PARAMETERS; // SAME URL AS USED IN POSTER
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
request.Method = "POST";
request.ContentType = "text/xml;charset=UTF-8";
string data = s;
Stream postStream = null;
using (StreamWriter requestStream = new StreamWriter(request.GetRequestStream()))
{
requestStream.Write(data);
}
HttpWebResponse pervasiveResponse = (HttpWebResponse)request.GetResponse();
StreamReader sr1 = new StreamReader(pervasiveResponse.GetResponseStream(), System.Text.Encoding.Default);
string backstr = sr1.ReadToEnd();
}
else
{
throw new ArgumentNullException();
}
REST Starter Kit? WCF Web API (Glenn Block's project, now part of AppFabric int he 4.5 time frame? (although I believe there will be a standalone))? Roll your own joint?
Regardless, I think working with binary is the correct method to go. For that reason, I would start with something like this article. Not because I tried the code and think it is a great article, but merely because the article shows sending XML and I don't have time to find the client I wrote a few months ago. ;-)
If I can break free long enough to find my code, I will post a sample.
Oh, another tool you should look at is SoapUI. No, it is not just for testing SOAP, as it supports REST (and other methodologies) as well as SOAP. One nice benefit of using SoapUI is the ability to move the tests over to LoadUI and stress testing a service. If you are merely consuming services, it might not have the greatest value, of course.

Post with WebRequest

I am trying to post to google so I can log into Google Reader and download subscription list, but I am unable to find a way to post to google in the windows 7 phone sdk, does anyone have an example on how to do this?
*Edit: Sorry wasn't very clear I am trying use the POST method, to submit an email and password to google login and retrieve a sid. I have used WebClient and HttpWebRequest but all the examples I have seen to send post data, the api calls are not in the windows 7 phone sdk.
I don't know anything about the Google API you're trying to use, but if all you need is to send a POST request, you can certainly do that with WebClient or HttpWebRequest. With WebClient, you can use either WebClient.OpenWriteAsync() or WebClient.UploadStringAsync(), the documentation is here: http://msdn.microsoft.com/en-us/library/tt0f69eh%28v=VS.95%29.aspx
With HttpWebRequest, you'll need to set the Method property to "POST". Here's a basic example:
var request = WebRequest.Create(new Uri(/* your_google_url */)) as HttpWebRequest;
request.Method = "POST";
request.BeginGetRequestStream(ar =>
{
var requestStream = request.EndGetRequestStream(ar);
using (var sw = new StreamWriter(requestStream))
{
// Write the body of your request here
}
request.BeginGetResponse(a =>
{
var response = request.EndGetResponse(a);
var responseStream = response.GetResponseStream();
using (var sr = new StreamReader(responseStream))
{
// Parse the response message here
}
}, null);
}, null);
The WebClient class may be easier to use, but is less customizable. For instance, I haven't seen a way to be able to attach cookies to WebClient requests, or a way to set the Content-Type header when using WebClient.
Have you tried using RESTSharp for your Windows Phone 7 project? The latest release supports Windows Phone 7 and I have had no issues working with popular REST APIs with it. In your particular case where you are trying to use the Google Reader API, this article by Luke Lowry can possibly help.
Not sure what you've already used, but have you tried WebClient?
WebClient web = new WebClient();
web.DownloadStringCompleted += (s, e) =>
{
if (e.Error == null)
CodeHereToHandleSuccess();
else
CodeHereToHandleError(e.Error);
};
web.DownloadStringAsync(new Uri(theURLYoureTryingToUse));
There's also WebRequest to look at too, that might work for what you're doing.
Edit: As for your "POST" edit, webclient lets you do post:
web.OpenWriteAsync(new Uri(theURLYoureTryingToUse), "POST");
you also then have to add an OpenWriteCompleted handler.
not sure exactly what you're doing, so you'll need to add more info to your question.

Invoking a POST to an external site with C# (httpwebrequest)

This is driving me nuts and I can't figure out where I am dropping the ball. I've followed a few examples found via the googlemonsta to no avail. Any pointer to where I goofed would be greatly apperciated.
var writer = new StringWriter();
param = "location=" + Server.UrlEncode(param);
byte[] paramStream = Encoding.ASCII.GetBytes(param + "&param2=value");
var URL = "http://www.somesite.com";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 6.0; sv-SE; rv:1.9.1b2) Gecko/20081201 Firefox/3.1b2";
request.ContentLength = paramStream.Length;
using( var stream = request.GetRequestStream())
{
stream.Write(paramStream, 0, paramStream.Length);
}
var response = request.GetResponse();
string result;
using (var sr = new StreamReader(response.GetResponseStream()))
{
result = sr.ReadToEnd();
}
Thanks!
EDIT: As far as I can tell its hitting the site (i'm getting html back) but the params aren't pushed over. I'm basically getting where the values would appear had it been successful. I've tried removing the first & but didnt get anywhere.
EDIT: Edited code to reflect changes.
Possibly get rid of the & from the start of the first parameter? Other than that it basically looks okay. (Check the parameter names in your real code - where you've got "paramater" in the sample it should almost certainly be "parameter" - but we don't know what your real code looks like or what the real site expects.)
Please give more information about what's actually happening. We know it doesn't work, but there are a lot of different possible failure modes :)
One extra thought occurs - you haven't specified the content length. I'm not sure whether this is filled in automatically by WebRequest. It would be worth using WireShark to check whether or not it's present in the outbound request.
Just as a general point of practice, you should dispose of the WebResponse, and you don't need to call Close if you've already got a using statement for the response stream:
string result;
using (WebResponse response = request.GetResponse())
{
using (var sr = new StreamReader(response.GetResponseStream()))
{
result = sr.ReadToEnd();
}
}
Are you sure you have all the values neccessary for the post? I once had a case where there was a hidden input field on the form that was something like:
<input name="action" type="hidden" id="action" value="login">
and I had to supply that as a param as:
&action=login
Make sure you're not missing anything from the form is what I'm saying...
EDIT: One more thing: I just looked at my code again where I've done this, and noticed that I also had this line in there:
request.ContentLength = bytes.Length;
Not sure if you need that, but I noticed that you weren't setting the length.
It is not something as simple as a carriage-return/new-line after the parameters is it? Looking at some docs on HTTP on the internets, you apparently need a blank line afterwards.
(I would suggest telneting to the web server manually and pasting your request.)

Categories