Request canceled when downloading feed - c#

I have a worker role on Azure. Every two hours, i download products from 3 different affiliate company.
First time, when the job runs, it's works perfect. The next time the job should run, I get from one affiliate, "The request was aborted: The request was canceled." The 2 others works perfect.
It's not just once, every time. I have ask this affiliate company, but there is no problem. So it must be my code. I have this to download json doc:
using (var Client = new WebClient())
{
Client.Headers.Add("X-API-KEY", Key);
Data = Client.DownloadString(URL);
}
What have I missed?
UPDATE 1:
i have try this:
HttpWebRequest Req = (HttpWebRequest)WebRequest.Create(URL);
Req.KeepAlive = false;
Req.Headers.Add("X-API-KEY", Key);
Req.Method = "GET";
using (var Resp = Req.GetResponse())
{
using (var Reader = new StreamReader(Resp.GetResponseStream()))
{
Data = Reader.ReadToEnd();
}
}
Same problem.
UPDATE 2
Request 1
GET https://se.#####.com/1/stores.json HTTP/1.1
X-API-KEY: x.............N
Host: se.#####.com
Connection: Close
Response 1
HTTP/1.1 200
Server: nginx
Date: Mon, 08 Jun 2015 14:56:39 GMT
Content-Type: application/json
Transfer-Encoding: chunked
Connection: close
Set-Cookie: ci_session=..............; expires=Mon, 08-Jun-2015 16:56:39 GMT; Max-Age=7200; path=/
e30
{"status":true,"data":[................]}
0
Request 2
GET https://se.#####.com/1/stores.json HTTP/1.1
X-API-KEY: x.............N
Host: se.#####.com
Connection: Close
Response 2
HTTP/1.1 200
Server: nginx
Date: Mon, 08 Jun 2015 15:06:29 GMT
Content-Type: application/json
Transfer-Encoding: chunked
Connection: close
Set-Cookie: ci_session=..................; expires=Mon, 08-Jun-2015 17:06:29 GMT; Max-Age=7200; path=/
e30
{"status":true,"data":[.....................]}
0
UPDATE 3
[TestMethod]
public void DownloadTest()
{
Test();
Test();
Test();
}
private static void Test()
{
const string merchantsUrl = "https://se.#####.com/1/stores.json";
string Data;
var Req = (HttpWebRequest)WebRequest.Create(merchantsUrl);
Req.KeepAlive = false;
Req.Headers.Add("X-API-KEY", ".....");
Req.Method = "GET";
using (var Resp = Req.GetResponse())
{
using (var Reader = new StreamReader(Resp.GetResponseStream()))
{
Data = Reader.ReadToEnd();
}
}
}

Change the order of requests and see if the request to same company is failing?
By default WebClient opens a connection as KeepAlive which might be causing this issue. So try explicitly mentioning that KeepAlive mode is false.
Capture the request details for the first time and second time in fiddler or similar tools which could give you more details in tracking down the issue.

Related

Capture response information from (3rd party) web service on error

I have the following code, which submits XML to a 3rd party web service, which errors (intentionally, at the moment) on "req.GetResponse()" with the error, detailed below.
byte[] bytes = Encoding.ASCII.GetBytes(myXMLData);
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(myWebsite);
using (Stream os = req.GetRequestStream())
{
os.Write(bytes, 0, bytes.Length);
}
WebResponse response = req.GetResponse();
string responseStream = StringFromResponseStream(response);
Error from GetResponse()
Exception thrown: 'System.New.WebExtension' in System.dll
Additional information: The remote server returned an error: (400) Bad Request
When I trace this call in Fiddler, I can see that the response from the service, also includes a far more useful error (below; RAW view), which I am trying to get to:
HTTP/1.1 400 Bad Request
Date: Thu, 16 Jun 2016 10:42:26 GMT
Cache-Control: private
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
Content-Type: text/plain; charset=UTF-8
Content-Length: 54
Caseprovider-Credentials: <snip>
Caseprovider-Credentialshash: <snip>
Caseprovider-Apiversion: 15
Connection: close
No supported action 'SomeName' available for 'SomeValue'
Having a 'watch' on the variables doesn't seem to show where I might obtain this from (and quite possibly something simple that I have overlooked)
Have eventually found a resolution for the; where 'result' contains the content from the process; there's more to do, but this is the basics of what I needed.
using (var httpClient = new HttpClient())
{
httpClient.BaseAddress = new Uri(myWebSite);
httpClient.DefaultRequestHeaders.Accept.Clear();
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/xml"));
StringContent stringContent = new StringContent(myXMLData);
stringContent.Headers.ContentType = new MediaTypeHeaderValue("text/xml");
HttpResponseMessage httpResponseMessage = httpClient.PostAsync(httpClient.BaseAddress, stringContent).Result;
string result = httpResponseMessage.Content.ReadAsStringAsync().Result;
}

Content length is always negative

I don't know but content length is always negative even if repsonse has corrent Content-Length header. For example:
class Program
{
static void Main()
{
try
{
string result = Get("http://stackoverflow.com/");
Console.WriteLine("Response length = {0}", result.Length);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
static string Get(string adr)
{
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(adr);
req.UserAgent = "Mozilla/5.0 (Windows NT 6.3; rv:36.0) Gecko/20100101 Firefox/36.0";
req.Proxy = null;
req.KeepAlive = false;
req.Headers.Add("Accept-Language", "ru-RU,ru;q=0.9,en;q=0.8");
req.AllowAutoRedirect = true;
req.Timeout = 10000;
req.ReadWriteTimeout = 10000;
req.MaximumAutomaticRedirections = 10;
req.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
req.Method = WebRequestMethods.Http.Get;
using (var response = (HttpWebResponse) req.GetResponse())
{
using (var stream = response.GetResponseStream())
{
if (stream == null)
throw new NullReferenceException("Response stream is nulL!");
using (var reader = new StreamReader(stream, Encoding.Default))
{
Console.WriteLine("Content length = {0}", response.ContentLength);
return WebUtility.HtmlDecode(reader.ReadToEnd());
}
}
}
}
}
fiddler shows following output:
HTTP/1.1 200 OK
Date: Wed, 02 Sep 2015 20:36:42 GMT
Content-Type: text/html; charset=utf-8
Connection: keep-alive
Cache-Control: private, max-age=0
Cf-Railgun: fe8c0e42fd 44.42 0.042796 0030 3350
X-Frame-Options: SAMEORIGIN
X-Request-Guid: bc3ccb1f-1de5-4375-b30d-f3c89134cf86
Server: cloudflare-nginx
CF-RAY: 21fc0233f6652bca-AMS
Content-Length: 251540
But in program I get this:
how can it be fixed?
A couple of things:
When I try, stackoverflow.com does not set a Content-Length header, so it will come through as -1.
But, changing the URL to use a server which definitely does set a Content-Length header, e.g., www.theguardian.com, still produces the same result: -1.
I think it's your use of AutomaticDecompression on the HttpWebRequest object.
If you don't set that property the ContentLength property comes through correctly.
This means that it is Fiddler that is returning the content-length. The reason that Fiddler would do that is that you have the 'Stream' button pressed (or some otherway to indicate to fiddler you want to return 'Stream' or 'Chunked' data.
When a server returns 'Chunked' data, it sets the content-length to -1 -- you don't know the length of the content since you can have unlimited chunks.
If you unclick (or turn off) streaming, then fiddler returns its default 'buffered' response, which is an exact copy of the response from the server. Which of course will include that Content-Length header.
Literally just went through this -- HTH!

Call PHP based webservice

I'm working on a asp.net webapplication, build in C#. I have to implement a third party web-service that is created using PHP. It is a very simple service containing only one function. I added the service reference using the wsdl, so far so good.
When I call the web-service function with the correct parameters it always returns null. I started troubleshooting with SoapUI. I captured the soap message from the application and pasted it in SoapUI, executed it and it returned the correct message. Using Fiddler I discovered something weird in the response from the web-service as shown in the raw output:
HTTP/1.1 200 OK
Date: Wed, 21 Nov 2012 15:24:31 GMT
Server: Apache/2.2.16 (Unix) mod_ssl/2.2.16 OpenSSL/0.9.8o
X-Powered-By: PHP/5.2.13-pl1-gentoo
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Set-Cookie: PHPSESSID=ddc342cfe7e56e77456fe31b758bf3de; path=/
Vary: Accept-Encoding,User-Agent
Content-Encoding: gzip
Content-Length: 812
Keep-Alive: timeout=15, max=100
Connection: Keep-Alive
Content-Type: text/xml; charset=utf-8
?????????KS?0???`r?~?<??? ?I
I?????0??+?.????kK.????[E?????[???????}??g4
?1J???~w?i??<?M?+w??[>]ziIc???.?
???yvi?"x? F??d?Y?aR,4?X?
[UQ^F)?$`?
7??[?F"?$??h???S?a??4??Q?E??6Td,t6%Hg??w/)??????]??G* ?l[??&6?0?$??>??????~?????:??6??W#?a????E?G?
s??Z????§o?_??c??\???-???)?????cc??w???/??f??}?)??r???????T?/??? m??K??8? ?X?/F8?<???:?m???&f ?Z#[31?*?X,c?Z??0h"??aFb.?<??p??a???Q?B?r>????Z??5??6???????n\y?d?.??\??Hc]??
Z,?x??l???g?Q?*&???1?)??????^?????v??pQ???_y~??%??????*?
>???;??6?+?>???RQq?????a?(?Z????C?5???G??Ce??H?9??xYL|"??i?
e8?Vk???s???AK^?e~??
??(??Lt???r???vs????7??d?w???Jj-B????pt????c??MBi?s)Mo?.??^?aB3?x8&??:_K|???5???)[?M?Xc?j?zX?=G?i/??TO???g????5??c0??w???T??
The header is displayed correctly. The response is encoded and needs to be decoded. Both SoapUI and Fiddler are able to decode the response, but the proxy class can't and returns null.
How can I overcome this problem? Any help is greatly appreciated!
EDIT:
The way the service is called:
LisenceServiceFR.ServiceRegistration_PortTypeClient client = new LisenceServiceFR.ServiceRegistration_PortTypeClient();
LisenceServiceFR.aVehicleInfo info = client.getVehicleInfo("xxx", "xxx", licensePlate, "localhost");
Edit 2:
The response XML from Fiddler.
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://services.audaconfr.com/ServiceRegistration.wsdl">
<SOAP-ENV:Body>
<SOAP-ENV:getVehicleInfoResponse>
<aVehicle>
<ns1:errorCode>200</ns1:errorCode>
<ns1:errorMessage>Success</ns1:errorMessage>
<ns1:vehicleXml>
<vehicule>
<carr>MONOSPACE COMPACT</carr>
<carr_cg>CI</carr_cg>
<co2>152</co2>
<!-- etc -->
</vehicule>
</ns1:vehicleXml>
</aVehicle>
</SOAP-ENV:getVehicleInfoResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
I ended up using HttpWebRequest to call the webservice:
System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
doc.InnerXml = xml;
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(endPoint);
req.Timeout = 100000000;
if (proxy != null)
req.Proxy = new WebProxy(proxy, true);
req.Headers.Add("SOAPAction", "");
req.ContentType = "application/soap+xml;charset=\"utf-8\"";
req.Accept = "application/x-www-form-urlencoded";
req.Method = "POST";
Stream stm = req.GetRequestStream();
doc.Save(stm);
stm.Close();
WebResponse resp = req.GetResponse();
stm = resp.GetResponseStream();
StreamReader r = new StreamReader(stm);
string responseData = r.ReadToEnd();
XDocument response = XDocument.Parse(responseData);
/* extract data from response */
It was not the solution I was looking for, but is works like a charm.

How do I carry a cookie from a System.Net.HttpWebResponse to the next System.Net.HttpWebRequest?

I'm trying to do some automated web requests and need to maintain a cookie from one to the next. I can see that I'm getting back the cookie I want from the initial response, but I can't attach it to the next request.
c# code
// response part
using (var wresp = (System.Net.HttpWebResponse)wrequest.GetResponse())
{
// respblob gets returned and is accessible to the next request
respblob.CookieList = new List<System.Net.Cookie>();
foreach (System.Net.Cookie cook in wresp.Cookies)
{
respblob.CookieList.Add(cook);
}
// ... more stuff not related to cookies
}
// next request part
var wrequest = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(url);
wrequest.Method = "POST";
wrequest.ContentType = "application/x-www-form-urlencoded";
wrequest.CookieContainer = new System.Net.CookieContainer();
// request.CookieList contains one cookie as expected
// from the previous response
for (int j = 0; j < request.CookieList.Count; j++)
{
wrequest.CookieContainer.Add(request.CookieList[j]);
}
// .... write data to request body
// ... complete the request, etc
here is a recorded exchange for the two request/response actions.
request:
GET http://domain.com/Login.aspx?ReturnUrl=%2fDefault.aspx HTTP/1.1
Host: domain.com
Connection: Keep-Alive
response:
HTTP/1.1 200 OK
Date: Tue, 15 May 2012 17:17:52 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
X-AspNet-Version: 2.0.50727
Set-Cookie: ASP.NET_SessionId=zzz4fpb4alwi1du2yavx5tah; path=/; HttpOnly
Cache-Control: private
Content-Type: text/html; charset=utf-8
Content-Length: 24408
...html content...
next request:
POST http://domain.com/Login.aspx?ReturnUrl=%2fDefault.aspx HTTP/1.1
Host: domain.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 979
Expect: 100-continue
__LASTFOCUS=&__EVENTTARGET=&__EVENTARGUMENT=&__VIEWSTATE=viewstateclipped&__EVENTVALIDATION=validationclipped&ctl00%2524ContentPlaceHolder1%2524Login1%2524LoginButton=&ctl00%2524ContentPlaceHolder1%2524Login1%2524UserName=my.email%40example.com&ctl00%2524ContentPlaceHolder1%2524Login1%2524Password=myPassword
So even though the cookie exists in the HttpWebRequest CookieContainer, it doesn't get sent with the request. What am I doing wrong?
You should use the same CookieContainer instance for the both HttpWebRequest objects that you are using. simply create a CookieContainer instance once:
var cookieContainer = new CookieContainer();
and then have your both request objects use this instance:
var request1 = (HttpWebRequest)WebRequest.Create("http://example.com/url1");
// assign the cookie container for the first request
request1.CookieContainer = cookieContainer;
... go ahead and send the request and process the response
var request2 = (HttpWebRequest)WebRequest.Create("http://example.com/url2");
// reuse the same cookie container instance as the first request
request2.CookieContainer = cookieContainer;
... go ahead and send the request and process the response
Since you are using the same CookieContainer for the both requests, when the first request stores the cookie in this container, the cookie will be emitted alongside the second request automatically. This of course assumes that the second request is to the same domain as the first one.
Also since the cookie is a session cookie (HttpOnly flag) you cannot read its value from the client.

ETag not being returned by WebResponse Header in c#

I am trying to extract the ETag from the response header. It does exist in the response. I can see it using firebug and I can see it in the response object using the inspector:
Status: 200 OK
X-Api-Version: 1.3.2
Access-Control-Allow-Origin: *
X-Runtime: 0.151298
Connection: keep-alive
Content-Length: 8185
Cache-Control: public, max-age=11216
Content-Type: application/json; charset=utf-8
Date: Fri, 09 Mar 2012 01:40:05 GMT
Expires: Fri, 09 Mar 2012 04:47:01 GMT
ETag: "bd3fe1123a8f55e01ca859f4804e8fbe"
Last-Modified: Fri, 09 Mar 2012 00:47:01 GMT
Server: nginx/1.0.11
All the other code is working fine, making the HttpWebRequest, getting the respose etc. The only problem is I always get null when trying to get the ETag (which does existing in the response header).
Here is the simplified code:
var request = (HttpWebRequest)WebRequest.Create(validUri);
SetHeaders(); // helper function to set basic headers.
var response = request.GetResponse();
var stream = response.GetResponseStream();
var reader = new StreamReader(stream);
var result = reader.ReadToEnd();
var etag = response.Headers.Get("ETag");
Anyone know why I can't seem to extract the existing ETag?
Your code does not reproduce the problem you are describing. Your problem is in something that you have not mentioned. Here is a short complete program based on your code, that executes and does print out the value of ETag without a problem:
using System;
using System.IO;
using System.Net;
namespace SO9628006
{
class Program
{
static void Main()
{
var request = (HttpWebRequest)WebRequest.Create("http://www.fiddler2.com/Fiddler/Fiddler.css");
var response = request.GetResponse();
var stream = response.GetResponseStream();
var reader = new StreamReader(stream);
var result = reader.ReadToEnd();
var etag = response.Headers.Get("ETag");
Console.WriteLine(etag);
}
}
}
Output:
"6c3673ba919ec71:243"
Could you please provide short but complete program that illustrates your issue?

Categories

Resources