HttpWebRequest request = WebRequest.Create("http://google.com") as HttpWebRequest;
request.Accept = "application/xrds+xml";
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
WebHeaderCollection header = response.Headers;
Here google returns text. How to read it?
Your "application/xrds+xml" was giving me issues, I was receiving a Content-Length of 0 (no response).
After removing that, you can access the response using response.GetResponseStream().
HttpWebRequest request = WebRequest.Create("http://google.com") as HttpWebRequest;
//request.Accept = "application/xrds+xml";
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
WebHeaderCollection header = response.Headers;
var encoding = ASCIIEncoding.ASCII;
using (var reader = new System.IO.StreamReader(response.GetResponseStream(), encoding))
{
string responseText = reader.ReadToEnd();
}
The accepted answer does not correctly dispose the WebResponse or decode the text. Also, there's a new way to do this in .NET 4.5.
To perform an HTTP GET and read the response text, do the following.
.NET 1.1 ‒ 4.0
public static string GetResponseText(string address)
{
var request = (HttpWebRequest)WebRequest.Create(address);
using (var response = (HttpWebResponse)request.GetResponse())
{
var encoding = Encoding.GetEncoding(response.CharacterSet);
using (var responseStream = response.GetResponseStream())
using (var reader = new StreamReader(responseStream, encoding))
return reader.ReadToEnd();
}
}
.NET 4.5
private static readonly HttpClient httpClient = new HttpClient();
public static async Task<string> GetResponseText(string address)
{
return await httpClient.GetStringAsync(address);
}
I've just tried that myself, and it gave me a 200 OK response, but no content - the content length was 0. Are you sure it's giving you content? Anyway, I'll assume that you've really got content.
Getting actual text back relies on knowing the encoding, which can be tricky. It should be in the Content-Type header, but then you've got to parse it etc.
However, if this is actually XML (e.g. from "http://google.com/xrds/xrds.xml"), it's a lot easier. Just load the XML into memory, e.g. via LINQ to XML. For example:
using System;
using System.IO;
using System.Net;
using System.Xml.Linq;
using System.Web;
class Test
{
static void Main()
{
string url = "http://google.com/xrds/xrds.xml";
HttpWebRequest request = (HttpWebRequest) WebRequest.Create(url);
XDocument doc;
using (WebResponse response = request.GetResponse())
{
using (Stream stream = response.GetResponseStream())
{
doc = XDocument.Load(stream);
}
}
// Now do whatever you want with doc here
Console.WriteLine(doc);
}
}
If the content is XML, getting the result into an XML object model (whether it's XDocument, XmlDocument or XmlReader) is likely to be more valuable than having the plain text.
This article gives a good overview of using the HttpWebResponse object:How to use HttpWebResponse
Relevant bits below:
HttpWebResponse webresponse;
webresponse = (HttpWebResponse)webrequest.GetResponse();
Encoding enc = System.Text.Encoding.GetEncoding(1252);
StreamReader loResponseStream = new StreamReader(webresponse.GetResponseStream(),enc);
string Response = loResponseStream.ReadToEnd();
loResponseStream.Close();
webresponse.Close();
return Response;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://www.google.com");
request.Method = "GET";
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream dataStream = response.GetResponseStream();
StreamReader reader = new StreamReader(dataStream);
string strResponse = reader.ReadToEnd();
response.GetResponseStream() should be used to return the response stream. And don't forget to close the Stream and Response objects.
If you http request is Post and request.Accept = "application/x-www-form-urlencoded";
then i think you can to get text of respone by code bellow:
var contentEncoding = response.Headers["content-encoding"];
if (contentEncoding != null && contentEncoding.Contains("gzip")) // cause httphandler only request gzip
{
// using gzip stream reader
using (var responseStreamReader = new StreamReader(new GZipStream(response.GetResponseStream(), CompressionMode.Decompress)))
{
strResponse = responseStreamReader.ReadToEnd();
}
}
else
{
// using ordinary stream reader
using (var responseStreamReader = new StreamReader(response.GetResponseStream()))
{
strResponse = responseStreamReader.ReadToEnd();
}
}
Related
I am getting timeout exception on code bellow. Only this site is problematic. What is the problem?
string ackoURL = "https://www.zomato.com/sk/brno/u-heligonky-z%C3%A1brdovice-brno-st%C5%99ed/denn%C3%A9-menu";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(ackoURL);
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
//this code is never executed
}
I tried modifying SecurityProtocol, KeepAlive and simmilar things. Without success.
it waiting these headers
..and it worked
Uri u = new Uri("https://www.zomato.com/sk/brno/u-heligonky-z%C3%A1brdovice-brno-st%C5%99ed/denn%C3%A9-menu");
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(u);
request.AutomaticDecompression = DecompressionMethods.GZip;
request.Headers.Add("Accept-Language", "en-gb,en;q=0.5");
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
using(Stream stream = response.GetResponseStream())
{
using(StreamReader reader= new StreamReader(stream))
{
var result = reader.ReadToEnd();
}
}
}
I'm trying to refactor a console app that uses SOAP to get some API data. I saw that the original code isn't using any USING statements. I thought I would try to refactor the code to do so, however, I get an "Internal Server Error". I've looked this over an few times and I'm not seeing why this wouldn't work. If I switch back to the original code it works as expected.
This is the original code that works:
public static string ProcessSOAPRequest(string xml, string endPoint)
{
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(endPoint);
req.Timeout = 100000000;
req.Method = "POST";
Stream objStream = req.GetRequestStream();
doc.Save(objStream);
objStream.Close();
WebResponse resp = req.GetResponse();
objStream = resp.GetResponseStream();
StreamReader r = new StreamReader(objStream);
string data = r.ReadToEnd();
return data;
}
This is my attempt at refactoring with USING.
public static string ProcessSOAPRequest(string xml, string endPoint)
{
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(endPoint);
request.Timeout = 100000000;
request.Method = "POST";
using (WebResponse response = request.GetResponse())
using (Stream stream = response.GetResponseStream())
using (StreamReader reader = new StreamReader(stream))
{
return reader.ReadToEnd();
}
}
UPDATE: another attempt based on the responses. This time in the second USING statement it says that I can't use stream = response.GetResponseStream(); because "stream" is in a using statement.
var data = string.Empty;
using (Stream stream = request.GetRequestStream())
{
doc.Save(stream);
using (WebResponse response = request.GetResponse())
{
stream = response.GetResponseStream();
using (StreamReader reader = new StreamReader(stream))
{
data = reader.ReadToEnd();
}
}
}
return data;
Answer to the update:
The variable declared in a using statement is treated as readonly. I suggest you to declare a new variable and assign the response to that. Why? - Why is a variable declared in a using statement treated as readonly?
var data = string.Empty;
using (Stream stream = request.GetRequestStream())
{
doc.Save(stream);
using (WebResponse response = request.GetResponse())
{
var responseStream = response.GetResponseStream();
if (responseStream != null)
{
using (StreamReader reader = new StreamReader(responseStream))
{
data = reader.ReadToEnd();
}
}
}
}
return data;
should work.
My remote server is throwing a web exception as bad request. But I know there is more information included in the error than what I get. If I look at the details from the exception it does not list the actual content of the response. I can see the content-type, content-length and content-encoding only. If I run this same message through another library (such as restsharp) I will see detailed exception information from the remote server. How can I get more details from the response since I know the remote server is sending them?
static string getXMLString(string xmlContent, string url)
{
//string Url;
string sResult;
//Url = ConfigurationManager.AppSettings["UserURl"] + url;
var httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
httpWebRequest.ContentType = "application/xml";
httpWebRequest.Method = "POST";
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
streamWriter.Write(xmlContent);
streamWriter.Flush();
streamWriter.Close();
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
sResult = result;
}
}
return sResult;
}
EDIT : Have you tried with a simple try-catch to see if you can get more details ?
try
{
var response = (HttpWebResponse)(request.GetResponse());
}
catch(Exception ex)
{
var response = (HttpWebResponse)ex.Response;
}
In my recherches in an answer for you, I noticed that in code there was something about encoding, that you didn't specified. Look here for exemple with such code.
var encoding = ASCIIEncoding.ASCII;
using (var reader = new System.IO.StreamReader(response.GetResponseStream(), encoding))
{
string responseText = reader.ReadToEnd();
}
Or here, in the doc, also.
// Creates an HttpWebRequest with the specified URL.
HttpWebRequest myHttpWebRequest = (HttpWebRequest)WebRequest.Create(url);
// Sends the HttpWebRequest and waits for the response.
HttpWebResponse myHttpWebResponse = (HttpWebResponse)myHttpWebRequest.GetResponse();
// Gets the stream associated with the response.
Stream receiveStream = myHttpWebResponse.GetResponseStream();
Encoding encode = System.Text.Encoding.GetEncoding("utf-8");
// Pipes the stream to a higher level stream reader with the required encoding format.
StreamReader readStream = new StreamReader( receiveStream, encode );
Console.WriteLine("\r\nResponse stream received.");
Have you tried with such ?
I'm making a HttpWebRequest to a server. This is in JSON. Now, the response is encoded and looks like this:
�\b\0\0\0\0\0\0��A� #ѻ�U�0l�u�\v�v�...
I can see that my request succeeded in Fiddler. And I can see the response of the server is the right one. But, also in fiddler it requires me to decode the answer first.
I have no idea how to decode this in C#.
Here is a bit of sample code that should do exactly what you want. BatchCollection in my case is my own object that maps to the JSON and so it can be mapped after its de-compressed.
var request = (HttpWebRequest)WebRequest.Create(uri);
request.Method = "POST";
request.Headers = headers;
request.Headers.Add("Content-Encoding", "gzip");
request.AutomaticDecompression = DecompressionMethods.GZip;
request.ContentType = "application/json";
var json = JsonConvert.SerializeObject(batchCollection);
using (Stream requestStream = request.GetRequestStream())
{
var buffer = Encoding.UTF8.GetBytes(json);
using (GZipStream compressionStream = new GZipStream(requestStream, CompressionMode.Compress, true))
{
compressionStream.Write(buffer, 0, buffer.Length);
}
}
var response = (HttpWebResponse)request.GetResponse();
BatchCollection batchOut = null;
using (Stream responseStream = response.GetResponseStream())
{
var reader = new StreamReader(responseStream);
var jsonOut = reader.ReadToEnd();
reader.Close();
batchOut = JsonConvert.DeserializeObject<BatchCollection>(jsonOut);
}
return batchOut;
In a C# Windows Forms application I can get the contents of a webpage using:
string content = webClient.DownloadString(url);
And I can get the HTTP header using:
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "GET";
string response = ((HttpWebResponse)request.GetResponse()).StatusCode.ToString();
Is there a way to get both the contents and the HTTP status code (if it fails) in one trip to the server instead of twice?
Thanks.
You can read the data from the Stream inside the HttpWebResponse object:
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "GET";
using (var response = request.GetResponse())
using (var stream = response.GetResponseStream())
using (var reader = new StreamReader(stream))
{
HttpStatusCode statusCode = ((HttpWebResponse)response).StatusCode;
string contents = reader.ReadToEnd();
}
In this way you will have to detect the encoding by hand, or using a library to detect encoding. You can read the encoding as a string from the HttpWebResponse object as well, when one exists, it is inside the ContentType property. If the page is Html, then you will have to parse it for a possible encoding change in the top of the document or inside the head.
Read handling the encoding from ContentType header
var request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "GET";
string content;
HttpStatusCode statusCode;
using (var response = request.GetResponse())
using (var stream = response.GetResponseStream())
{
var contentType = response.ContentType;
Encoding encoding = null;
if (contentType != null)
{
var match = Regex.Match(contentType, #"(?<=charset\=).*");
if (match.Success)
encoding = Encoding.GetEncoding(match.ToString());
}
encoding = encoding ?? Encoding.UTF8;
statusCode = ((HttpWebResponse)response).StatusCode;
using (var reader = new StreamReader(stream, encoding))
content = reader.ReadToEnd();
}
WebClient
I assume you use WebClient because its easy webrequest-to-string handling. Unfortunately, WebClient does not expose the HTTP response code. You can either assume the response was positive (2xx) unless you get an exception and read it:
try
{
string content = webClient.DownloadString(url);
}
catch (WebException e)
{
HttpWebResponse response = (System.Net.HttpWebResponse)we.Response;
var statusCode = response.StatusCode;
}
Or if you're really interested in the success code you can use reflection as explained here.
HttpClient
You can also use HttpClient if you're on .NET 4.5, which does expose the response code, as explained here:
using (HttpClient client = new HttpClient())
{
HttpResponseMessage response = await client.GetAsync(url);
string content = await response.Content.ReadAsStringAsync();
var statusCode = response.StatusCode;
}
HttpWebRequest
Alternatively, you can just use HttpWebRequest to get the status and response as explained here:
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "GET";
var response = (HttpWebResponse)request.GetResponse();
using (Stream stream = response.GetResponseStream())
{
StreamReader reader = new StreamReader(stream);
string content = reader.ReadToEnd();
var statusCode = response.StatusCode;
}
I think, you have not realised, that in the second case you have access to the content as well (although it takes a little more effort to get as a string).
Look at the Microsoft documentation: http://msdn.microsoft.com/en-us/library/system.net.httpwebresponse.getresponsestream(v=vs.110).aspx which shows you how to ge a response stream from the web response, and then how to get the string data from that stream.
And I can get the HTTP header using:
request.Method = "GET";
Method GET returns HEAD and BODY sections in response.
HTTP also support a method HEAD - which returns HEAD section only.
You can get BODY from HttpWebResponse using GetResponseStream method.