How to return GetResponseStream in xml? - c#

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.

Related

Get xml from website by webrequest then deserialize it and show in console

Hello i learning about this stuff an i need to send request to site get xml in response than deserialize it and see anything what was inside... i created request deserialize method and stream method and Xml Schema but now i dont know what next and it doest working so if anybody know about some nice tutorial pls give me link.
public static class LoadXml
{
public static root material;
public static void LoadXML()
{
var serviceUrl = "http://api.deezer.com/2.0/artist/27&output=xml";
string serviceName = "Deezer";
HttpWebRequest request = null;
WebResponse response = null;
request = WebRequest.Create(serviceUrl) as HttpWebRequest;
request.Method = "GET";
request.ContentType = " text/xml";
material = Deserialize<root>(GetResponseStream(request, response, serviceName));
Console.WriteLine(material.ToString());
}
public static T Deserialize<T>(MemoryStream stream)
{
XmlSerializer serializer = new XmlSerializer(typeof(T));
T result = (T)serializer.Deserialize(stream);
return result;
}
public static MemoryStream GetResponseStream(HttpWebRequest request, WebResponse response, string debugServiceName)
{
response = request.GetResponse();
MemoryStream stream = new MemoryStream();
response.GetResponseStream().CopyTo(stream);
stream.Position = 0;
return stream;
}
}
Place (or load) the results into an [XDocument][1] and work with it from there by manipulating and extracting data from the document.
Using the url as a starting point this is a snippet (easier way to load; try it) where we load it and then look at a target child node if the structure returned was (\root\name):
XDocument doc = XDocument.Load(#"http://api.deezer.com/2.0/artist/27&output=xml");
Console.WriteLine ( doc.ToString() );
/*
<root>
<id><![CDATA[27]]></id>
<name><![CDATA[Daft Punk]]></name>
<link><![CDATA[http://www.deezer.com/artist/27]]></link>
<picture><![CDATA[http://api.deezer.com/2.0/artist/27/image]]></picture>
<nb_album><![CDATA[54]]></nb_album>
<nb_fan><![CDATA[592180]]></nb_fan>
<radio><![CDATA[1]]></radio>
<type><![CDATA[artist]]></type>
*/
Console.WriteLine ( doc.Element("root").Element("name").Value);
// Outputs:
// Daft Punk
Update Alternate Load (Parse)
var xml = #"
<root>
<id><![CDATA[27]]></id>
<name><![CDATA[Daft Punk]]></name>
<link><![CDATA[http://www.deezer.com/artist/27]]></link>
<picture><![CDATA[http://api.deezer.com/2.0/artist/27/image]]></picture>
<nb_album><![CDATA[54]]></nb_album>
<nb_fan><![CDATA[592180]]></nb_fan>
<radio><![CDATA[1]]></radio>
<type><![CDATA[artist]]></type>
</root>";
var doc = XDocument.Parse( xml );
Console.WriteLine ( doc.Element("root").Element("name").Value);
// Outputs
// Daft Punk

Check if a URL is a valid Feed

I'm using Argotic Syndication Framework for processing feeds.
But the problem is, if I pass a URL to Argotic, which is not a valid feed (for example, http://stackoverflow.com which is a html page, not feed), the program hangs (I mean, Argotic stays in an infinity loop)
So, How to check if a URL is pointing to a valid feed?
From .NET 3.5 you can do this below. It will throw an exception if it's not a valid feed.
using System.Diagnostics;
using System.ServiceModel.Syndication;
using System.Xml;
public bool TryParseFeed(string url)
{
try
{
SyndicationFeed feed = SyndicationFeed.Load(XmlReader.Create(url));
foreach (SyndicationItem item in feed.Items)
{
Debug.Print(item.Title.Text);
}
return true;
}
catch (Exception)
{
return false;
}
}
Or you can try parsing the document by your own:
string xml = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<event>This is a Test</event>";
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(xml);
Then try checking the root element. It should be the feed element and have "http://www.w3.org/2005/Atom" namespace:
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" xmlns:re="http://purl.org/atompub/rank/1.0">
References:
http://msdn.microsoft.com/en-us/library/system.servicemodel.syndication.syndicationfeed.aspx
http://dotnet.dzone.com/articles/systemservicemodelsyndication
you can use Feed Validation Service. It has SOAP API.
You can check the content type. It has to be text/xml. See this question to find the content type.
you can use this code:
var request = HttpWebRequest.Create("http://www.google.com") as HttpWebRequest;
if (request != null)
{
var response = request.GetResponse() as HttpWebResponse;
string contentType = "";
if (response != null)
contentType = response.ContentType;
}
thanks to the answer of the question
Update
To check if it is a feed address you can use W3C Feed Validation service.
Update2
as BurundukXP said it has a SOAP API. to work with it you can read the answer of this question.
If you want to just have it transformed into valid RSS/ATOM, you can use http://feedcleaner.nick.pro/ to have it sanitized. Alternatively, you can fork the project.

Timeout error when loading Xml from URL

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;
}

SPML (service provisioning markup language) / C#.Net help please!

Sorry for virtually begging for help here but I've been tasked to work on the above and cannot find any adequate resources to help me. Here's the details:
The company has Identity management software which provides an SPML (SOAP) 'feed' of changes to user entitities
(If I've got this right) the SPML driver makes a POST request to a URL on my server which sends those changes
Whatever sits under that URL has to then process the posted information (XML)
Point 3 is my bit. I have no idea what to write. Asmx? Aspx? Ashx? Commodore 64 cassette tape? Apparently the SPML driver needs a 200 response - it will get that anyway when the processing has taking place no? Is there anything more to it that I'm not getting?
Any help, pointers, guidance or advising me to give up and get a new hobby, would be much appreciated.
Thanks.
EDIT..............
Have got a simple soap driver going (for the purposes of testing) which posts xml to an aspx page which then, in turn, consumes the POST and saves the xml. Thanks to J Benjamin (below) and http://www.eggheadcafe.com/articles/20011103.asp for the kick-start.
SOAP DRIVER (works on page load)
protected void Page_Load(object sender, EventArgs e)
{
XmlDocument doc = new XmlDocument();
doc.Load(MySite.FileRoot + "testing\\testxml.xml");
HttpWebRequest req =
(HttpWebRequest)WebRequest.Create("http://localhost/mysite/testing/reader.aspx");
req.ContentType = "text/xml; charset=\"utf-8\"";
req.Method = "POST";
req.Headers.Add("SOAPAction", "\"\"");
Stream stm = req.GetRequestStream();
doc.Save(stm);
stm.Close();
WebResponse resp = req.GetResponse();
stm = resp.GetResponseStream();
StreamReader r = new StreamReader(stm);
Response.Write(r.ReadToEnd());
}
SOAP READER (reads xml posted when called)
protected void Page_Load(object sender, EventArgs e)
{
String Folderpath = "c:\\TestSOAP\\";
if (!Directory.Exists(Folderpath))
{
Directory.CreateDirectory(Folderpath);
}
Response.ContentType = "text/xml";
StreamReader reader = new StreamReader(Request.InputStream);
String xmlData = reader.ReadToEnd();
String FilePath = Folderpath + DateTime.Now.ToFileTimeUtc() + ".xml";
File.WriteAllText(FilePath, xmlData);
}
The next step is to try consume the SPML service (which is a Java-driven Novell type thing) - if I have any problems, I will post back here!!
Thanks all.. :)
Maybe I'm misunderstanding, but this sounds similar to how I'm handling URLs in my web service. We're handling logic based on URLs, do the logic, wrap it up in XML and respond with the XML object. Here's a simple example (by simple, I mean one of the few that doesn't require authentication)
The code below simply returns an XML object containing an AppSetting. The XML response is below as well (with some identifying values removed).
[OperationContract]
[WebInvoke(Method = "POST", UriTemplate = "External/Application/{ApplicationGUID}/APIHost/")]
public Response GetAPIHostName(Request request, string ApplicationGUID)
{
Response response = new Response();
try
{
APIHost apiHost = new APIHost
{
APIHostname = System.Configuration.ConfigurationManager.AppSettings["PlayerAPIHostname"]
};
response.ResponseBody.APIHost = apiHost;
response.ResponseHeader.UMResponseCode = (int) UMResponseCodes.OK;
}
catch (GUIDNotFoundException guidEx)
{
response.ResponseHeader.UMResponseCode = (int)UMResponseCodes.NotFound;
response.ResponseHeader.UMResponseCodeDetail = guidEx.Message;
}
catch (Exception ex)
{
UMMessageManager.SetExceptionDetails(request, response, ex);
if (request != null)
Logger.Log(HttpContext.Current, request.ToString(), ex);
else
Logger.Log(HttpContext.Current, "No Request!", ex);
}
response.ResponseHeader.HTTPResponseCode = HttpContext.Current.Response.StatusCode;
return response;
}
/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
200
200
localhost

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