Timeout error when loading Xml from URL - c#

I am doing task of loading the live xml file (from live url) to XmlDataDocument, but every time I am getting error:
The operation has timed out
The code is as follows, The url containing the xml feeds , I want to load it into xmlDoc.
XmlDataDocument xmlDoc = new XmlDataDocument();
xmlDoc.Load("http://www.globalgear.com.au/productfeed.xml");
Please suggest any solution.

Don't use the Load method of the XmlDataDocument class directly; you have little to no way of influencing the behaviour when it comes to long running HTTP requests.
Instead, use the HttpWebRequest and HttpWebResponse classes to do the work for you, and then load the subsequent response into your document.
For example:
HttpWebRequest rq = WebRequest.Create("http://www.globalgear.com.au/productfeed.xml") as HttpWebRequest;
//60 Second Timeout
rq.Timeout = 60000;
//Also note you can set the Proxy property here if required; sometimes it is, especially if you are behind a firewall - rq.Proxy = new WebProxy("proxy_address");
HttpWebResponse response = rq.GetResponse() as HttpWebResponse;
XmlTextReader reader = new XmlTextReader(response.GetResponseStream());
XmlDocument doc = new XmlDocument();
doc.Load(reader);
I've tested this code in a local app instance and the XmlDocument is populated with the data from your URL.
You can also substitute in XmlDataDocument for XmlDocument in the example above - I prefer to use XmlDocument as it's not (yet) marked as obsolete.
I've wrapped this in a function for you:
public XmlDocument GetDataFromUrl(string url)
{
XmlDocument urlData = new XmlDocument();
HttpWebRequest rq = (HttpWebRequest)WebRequest.Create(url);
rq.Timeout = 60000;
HttpWebResponse response = rq.GetResponse() as HttpWebResponse;
using (Stream responseStream = response.GetResponseStream())
{
XmlTextReader reader = new XmlTextReader(responseStream);
urlData.Load(reader);
}
return urlData;
}
Simply call using:
XmlDocument document = GetDataFromUrl("http://www.globalgear.com.au/productfeed.xml");

To my knowledge there is no easy way to adjust the timeout with the method you are using.
The easiest change would be to use the webclient class and set the timeout property. This is described here http://w3ka.blogspot.co.uk/2009/12/how-to-fix-webclient-timeout-issue.html. Then use downloadfile on the webclient. Then load the saved file in the XMLDocument.

Set a timeout for your web request:
using System;
using System.Net;
using System.Xml;
namespace Shelver
{
class Program
{
static void Main(string[] args)
{
WebRequest requ = WebRequest.Create("http://www.globalgear.com.au/productfeed.xml");
requ.Timeout = 10 * 60 * 1000; // 10 minutes timeout and not 100s as the default.
var resp = requ.GetResponse();
Console.WriteLine("Will download {0:N0}bytes", resp.ContentLength);
var stream = resp.GetResponseStream();
XmlDocument doc = new XmlDocument();
doc.Load(stream);
}
}
}
This example will set it to 10 minutes.

In addition to the previous answers, which should be the first step towards fixing this, I continued to get this exception despite having already loaded the response and closing the connections.
The solution for me: the Load() and LoadXml() methods would throw their own Timeout exception if the value provided wasn't actually XML. Checking to verify that the response content was XML worked in our case (this will require that the host you are getting your response from actually sets content types).
Building upon dash's answer:
public XmlDocument GetDataFromUrl(string url)
{
XmlDocument urlData = new XmlDocument();
HttpWebRequest rq = (HttpWebRequest)WebRequest.Create(url);
rq.Timeout = 60000;
HttpWebResponse response = rq.GetResponse() as HttpWebResponse;
// New check added to dash's answer.
if (response.ContentType.Contains("text/xml")
{
using (Stream responseStream = response.GetResponseStream())
{
XmlTextReader reader = new XmlTextReader(responseStream);
urlData.Load(reader);
}
}
return urlData;
}

Related

Transform XML returned from a web request using XLST

I see several questions that are close to this but none exactly cover it:
How to apply an XSLT Stylesheet in C#
XSLT Transform of XML using Xml data from a web form
How to transform an xml structure generated from a request to a web services
I can cobble something together from these but I worry I am passing it through too many steps to be efficient.
What I currently have is this, to read XML from a HTTP web request:
WebRequest request = WebRequest.Create(url);
WebResponse response = request.GetResponse();
Stream stream = response.GetResponseStream();
StreamReader streamReader = new StreamReader(stream);
string xml = streamReader.ReadToEnd();
This was before the need to apply an XLST transform was needed. Now I have a (possibly null) XslCompiledTransform object.
So I want to add a block like:
if(transform != null)
{
xml = transform.Transform(xml);
}
Clearly this isn't possible as written. I see StringReaders and XmlReaders can be created but is it inefficient to get my xml as a string and then push it back into another object? Can I use my stream or streamReader objects directly to support the same basic flow, but with optional transformation?
Personally I'd use the XmlDocument.Load() function to load the XML from the URL, without using WebRequest in this case.
You can pass the XmlDocument Straight to XSLCompiledTransform.Transform() then.
XmlDocument doc = new XmlDocument();
doc.Load(url);
if (transform != null)
{
XmlDocument tempDoc = new XmlDocument();
using (XmlWriter writer = tempDoc.CreateNavigator().AppendChild())
{
transform.Transform(doc, writer);
}
doc = tempDoc;
} //Use your XmlDocument for your transformed output

How to return GetResponseStream in xml?

I am trying to create web request, which sends XML via POST call and would like to return the response back in XML.
I am having a little difficulty with the response back xml, as I am little I unsure how do I set that up int he code below. here is my attempt:
// Attempt to receive the WebResponse to the WebRequest.
using (HttpWebResponse hwresponse = (HttpWebResponse)hwrequest.GetResponse())
{
statusCode = (int)hwresponse.StatusCode;
if (hwresponse != null)
{ // If we have valid WebResponse then read it.
using (StreamReader reader = new StreamReader(hwresponse.GetResponseStream()))
{
// XPathDocument doc = new XPathDocument(reader);
string responseString = reader.ReadToEnd();
if (statusCode == 201 )
{
// var response = new XElement("Status",
// new XElement("status_code", statusCode),
// new XElement("resources_created",
//// new XElement("Link"),
// new XElement("href"),
// new XElement("title")
// ),
// new XElement("warnings")
// );
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(responseString);
XmlNodeList address = xmlDoc.GetElementsByTagName("Status");
responseData = xmlDoc.ToString();
reader.Close();
}
}
}
hwresponse.Close();
}
}
catch (WebException e)
{
if (e.Status == WebExceptionStatus.ProtocolError)
{
// XmlDocument xmlDoc = new XmlDocument();
// XmlNodeList address = xmlDoc.GetElementsByTagName("Status", statusCode);
// xmlDoc.Load(xmlDoc);
}
// if (e.Status == WebExceptionStatus.ProtocolError)
// {
// responseData = "Status Code : {0}" + ((HttpWebResponse)e.Response).StatusCode + "Status Description : {0}" + ((HttpWebResponse)e.Response).StatusDescription;
// responseData "Status Description : {0}" + ((HttpWebResponse)e.Response).StatusDescription;
// }
}
I would like to be able to return the response back in the following XML format:
<status>
<status_code>201</status_code>
<etag>12345678</etag>
<resources_created>
<link
rel="http://api-info.com"
href="http://api-info.com/tag/Some%20Tag"
title="Subscriber Tag (Some Tag)" />
</resources_created>
<warnings>
<warning>Some Warning Message</warning>
</warnings>
</status>
I would also like to ask, if my 'StatusCode' should be setup as if conditions or try&catch.
Any guide would be most helpful. Many thanks.
You may not have any control over what is sent to you but you can ask for xml with an Accept header.
hwrequest.Accept = "application/xml";
However, you will have no control over the structure.
Yes, you should handle the response status (200, 201, 404 etc.) using If/Else statements and NOT rely on try/catch to handle your logic. Try/Catch is for error handling, and not a place to handle regular application flow.
For the Web Requests you are using an obsolete API. Unless there is a specific limitation that forces you to use HttpWebRequest and HttpWebResponse, you should use a newer (and simpler) API like WebClient or HttpClient (only .NET 4.5).
http://msdn.microsoft.com/en-us/library/system.net.webclient%28v=vs.110%29.aspx
http://msdn.microsoft.com/en-us/library/system.net.http.httpclient%28v=vs.118%29.aspx
For response handling i would advice using Linq to XML instead of the old XmlDocument API.
If your response XML has the "status" element at the root of the XML document, then you can do:
var xmlDoc = XDocument.Load(reader);
var statusXml = xmlDoc.ToString();
If the "status" element is a children of another root XML element, then you can do:
var xmlDoc = XDocument.Load(reader);
var statusElement = xmlDoc.Root.Element("status");
var statusXml = statusElement.ToString();
If you still want to use the old HTTP API, You can get rid of
string responseString = reader.ReadToEnd();
and pass directly the StreamReader in the XDocument.Load method as in my example.
In case you upgrade your solution to use e.g. WebClient you can use the DownloadString() method, and then load the string result into the XDocument.Load() method.

System.Net.WebException: The operation has timed out On certain computer only

I will preface the code and explanation with the fact that I was able to run this code on the computers that my school has, and I have had multiple friends successfully run the code on their machines.
I have some C# code which is supposed to retrieve the RSS feed from a URL
public void GetRSS(string url)
{
// Connect to the web server
HttpWebRequest wr = (HttpWebRequest)WebRequest.Create(url);
// Set the HTTP properties
wr.Timeout = 9000;
// Read the Response
WebResponse resp = wr.GetResponse();
Stream stream = resp.GetResponseStream();
// Load XML Document
XmlTextReader reader = new XmlTextReader(stream);
reader.XmlResolver = null;
xml = new XmlDocument();
xml.Load(reader);
//Select the "RSS items" from the feed
XmlNodeList items = xml.SelectNodes("//item");
//Open a serializer
XmlSerializer serializer =
new XmlSerializer(typeof(Rss));
using (XmlReader xreader = XmlReader.Create(new StringReader(xml.OuterXml)))
{
reader.MoveToContent();
rss = (Rss)new XmlSerializer(typeof(Rss)).Deserialize(xreader);
}
resp.Close();
}
This always throws "System.Net.WebException: The operation has timed out" on the line
WebResponse resp = wr.GetResponse();
My issue is that I cannot see why exactly this isn't working. I assume that no connection can be made to the URL, but no matter how many URLs I try, it never works. It just hangs for a few seconds and then comes up with the error.
To clarify, the program executes flawlessly on every machine I have tried it on aside from my home computer, on which I need to write the program.

How to specify timeout for XmlReader?

I am reading rss with xml reader.
And when url is bad it takes 60 seconds to fail for it. How i can specify timeout?
using (XmlReader reader = XmlReader.Create(url, settings))
I don't know if it's possible to change the XmlReader timeout, but maybe you can do something different:
Use WebRequest to get the xml (this does have a Timeout property) and feed XmlReader this xml after you have received it:
WebRequest request = WebRequest.Create(url);
request.Timeout = 5000;
using (WebResponse response = request.GetResponse())
using (XmlReader reader = XmlReader.Create(response.GetResponseStream()))
{
// Blah blah...
}
You can create your own WebRequest and create an XmlReader from the response stream. See the response to this question for details:
Prevent or handle time out with XmlReader.Create(uri)
Pass your own stream to the XmlReader.Create call. Set whatever timeout you like.
Another option is to do this
var settings = new XmlReaderSettings();
settings.XmlResolver = resolver;
// Create the reader.
XmlReader reader = XmlReader.Create("http://serverName/data/books.xml", settings);
Where the resolver instance is a custom class that changes the url fetching behavior as described in the documentation at the link below.
https://learn.microsoft.com/en-us/dotnet/api/system.xml.xmlurlresolver?view=net-6.0#extending-the-xmlurlresolver-class

How to consume an HTTP webservice in Asp.net?

I want to generate html content based on a result returned by http url.
http://www.zillow.com/webservice/GetDeepSearchResults.htm?zws-id=X1-ZWz1c239bjatxn_5taq0&address=2114+Bigelow+Ave&citystatezip=Seattle%2C+WA
This page will give you some XML results. I want to convert to use that XML to generate HTML. I am not getting any idea where to start? Would someone offer any guidelines or sample code for asp.net?
For details: http://www.zillow.com/howto/api/GetDeepSearchResults.htm
To fetch the data you can use the HttpWebRequest class, this is an example I have to hand but it may be slightly overdone for your needs (and you need to make sure you're doing the right thing - I suspect the above to be a GET rather than a POST).
Uri baseUri = new Uri(this.RemoteServer);
HttpWebRequest rq = (HttpWebRequest)HttpWebRequest.Create(new Uri(baseUri, action));
rq.Method = "POST";
rq.ContentType = "application/x-www-form-urlencoded";
rq.Accept = "text/xml";
rq.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
Encoding encoding = Encoding.GetEncoding("UTF-8");
byte[] chars = encoding.GetBytes(body);
rq.ContentLength = chars.Length;
using (Stream stream = rq.GetRequestStream())
{
stream.Write(chars, 0, chars.Length);
stream.Close();
}
XDocument doc;
WebResponse rs = rq.GetResponse();
using (Stream stream = rs.GetResponseStream())
{
using (XmlTextReader tr = new XmlTextReader(stream))
{
doc = XDocument.Load(tr);
responseXml = doc.Root;
}
if (responseXml == null)
{
throw new Exception("No response");
}
}
return responseXml;
Once you've got the data back you need to render HTML, lots and lots of choices - if you just want to convert what you've got into HTML with minimal further processing then you can use XSLT - which is a question all on its own. If you need to do stuff with it then the question is too vague and you'll need to be more specific.
Create a xsl stylesheet, and inject the stylesheet element into the resulting xml from teh page

Categories

Resources