Ignore failure codes from WebRequest? - c#

I'm calling an XML webservice URL from C# using standard WebRequest code:
WebRequest request = WebRequest.Create(MethodCall);
WebResponse response = request.GetResponse();
Stream stream = response.GetResponseStream();
StreamReader streamReader = new StreamReader(stream);
string xml = streamReader.ReadToEnd();
The service in question returns XML; in case of errors you often still get XML returned with detailed error information, however it also returns an HTTP error code 400.
Running the query through Chrome I can see the XML and the error code in the dev-tools but my C# code throws a .Net WebException in the GetResponse() call so I never see the detailed error information.
Is there a way I can tell .Net not to throw exception but still to report the error code, so I can inspect the returned XML?

Change WebResponse response = request.GetResponse(); to
WebResponse response;
try
{
response = request.GetResponse();
}
catch (WebException ex)
{
response = (ex.Response as WebResponse);
if (response == null)
throw;
}
This should work.

Related

Catch External API Error Message as in Postman Body

I am using the following code to complete an External API call.
WebResponse response = request.GetResponse();
string JSONResult = null;
var data = response.GetResponseStream();
using (var reader = new StreamReader(data))
{
JSONResult = reader.ReadToEnd();
}
When there is an exception on the external API, the request.GetResponse throws an error. However, I cannot get the message that is displayed, e.g.
{
"Message": "No HTTP resource was found that matches the request URI '<site>/Foo'.",
"MessageDetail": "No type was found that matches the controller named 'Foo'."
}
Whilst this is displayed in Fiddler and Postman, I cannot get this message anywhere when it is thrown as an exception.
How do I get this specific details when an error on an external API's call is made?
You need to catch the exception and then read the response stream of the exception. Reading the exception's response stream is the same as reading the response of the request. Here is how:
WebRequest request =
WebRequest.Create("http://...");
WebResponse response = null;
try
{
response = request.GetResponse();
}
catch (WebException webEx)
{
if (webEx.Response != null)
{
using (var errorResponse = (HttpWebResponse)webEx.Response)
{
using (var reader = new StreamReader(errorResponse.GetResponseStream()))
{
string error = reader.ReadToEnd();
// TODO: use JSON.net to parse this string
}
}
}
}
Do not put all your code inside the above try block because you are only try(ing) and catch(ing) the request.GetResponse(). The rest of your code needs to go outside that try catch block so you can catch the exceptions from that code separately.

GDax API GET request always returns Error 400

I'm trying to get the order book from GDAX (link to documentation of the call) but when doing it from the c# executable I always get Error 400 - Bad request.
When taking the actual URL and pasting it into my browser, it works fine.
String URL = "https://api.gdax.com/products/BTC-USD/book?level=2";
WebRequest request = WebRequest.Create(URL);
WebResponse response = request.GetResponse();
The actual issue with your API call is , the API is expecting a user-agent string while making the request: Below is the code in working condition:
try
{
String URL = "http://api.gdax.com/products/BTC-USD/book?level=2";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL);
request.UserAgent = ".NET Framework Test Client";
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
var encoding = ASCIIEncoding.ASCII;
using (var reader = new System.IO.StreamReader(response.GetResponseStream(), encoding))
{
string responseText = reader.ReadToEnd();
}
}
catch(WebException ex)
{
HttpWebResponse xyz = ex.Response as HttpWebResponse;
var encoding = ASCIIEncoding.ASCII;
using (var reader = new System.IO.StreamReader(xyz.GetResponseStream(), encoding))
{
string responseText = reader.ReadToEnd();
}
}
Basically ProtocolError indicates that you have received the response but there is an error related to protocol, which you can observe, when you read the response content from exception. I have added catch to handle the exception and read ex.Response (which is HttpWebResponse) and could see that the API is asking for user-agent to be suppllied while making the call. I got to see the error as "{"message":"User-Agent header is required."}"
You can ignore the code inside the exception block, I used it only to see what is the actual response message, which contains actual error details
Note: I have boxed WebRequest to HttpWebRequest to have additional http protocol related properties and most importantly "UserAgent" property which is not available with the WebRequest class.
You need to Accept the certificarte, Google for access to a https webrequest.
Like this

deserialize rest api xml response c#

I have a task to make a call to REST API which gives an XML output. The xml output should be deserialized into a .NET class which can be queried later. I am not sure where I am doing wrong, but the code gives an error. On debugging the code, I figured out the issue is when trying to deserialize the response stream it gives an error saying 'responsestream.Length threw an exception of type System.NotSupportedException'. Please help me to figure out this issue.
Below is my sample code.
WebRequest request = (WebRequest)WebRequest.CreateHttp(apiurl);
request.Method = "GET";
using (WebResponse response = request.GetResponse())
{
Stream responsestream = response.GetResponseStream();
XmlSerializer serializer = new XmlSerializer(typeof(List<ResponseClass>));
var apiresponse = (List<ResponseClass>)serializer.Deserialize(responsestream);
}

How to get error information when HttpWebRequest.GetResponse() fails

I am initiating an HttpWebRequest and then retrieving it's response. Occasionally, I get a 500 (or at least 5##) error, but no description. I have control over both endpoints and would like the receiving end to get a little bit more information. For example, I would like to pass the exception message from server to client. Is this possible using HttpWebRequest and HttpWebResponse?
Code:
try
{
HttpWebRequest webRequest = HttpWebRequest.Create(URL) as HttpWebRequest;
webRequest.Method = WebRequestMethods.Http.Get;
webRequest.Credentials = new NetworkCredential(Username, Password);
webRequest.ContentType = "application/x-www-form-urlencoded";
using(HttpWebResponse response = webRequest.GetResponse() as HttpWebResponse)
{
if(response.StatusCode == HttpStatusCode.OK)
{
// Do stuff with response.GetResponseStream();
}
}
}
catch(Exception ex)
{
ShowError(ex);
// if the server returns a 500 error than the webRequest.GetResponse() method
// throws an exception and all I get is "The remote server returned an error: (500)."
}
Any help with this would be much appreciated.
Is this possible using HttpWebRequest and HttpWebResponse?
You could have your web server simply catch and write the exception text into the body of the response, then set status code to 500. Now the client would throw an exception when it encounters a 500 error but you could read the response stream and fetch the message of the exception.
So you could catch a WebException which is what will be thrown if a non 200 status code is returned from the server and read its body:
catch (WebException ex)
{
using (var stream = ex.Response.GetResponseStream())
using (var reader = new StreamReader(stream))
{
Console.WriteLine(reader.ReadToEnd());
}
}
catch (Exception ex)
{
// Something more serious happened
// like for example you don't have network access
// we cannot talk about a server exception here as
// the server probably was never reached
}
I came across this question when trying to check if a file existed on an FTP site or not. If the file doesn't exist there will be an error when trying to check its timestamp. But I want to make sure the error is not something else, by checking its type.
The Response property on WebException will be of type FtpWebResponse on which you can check its StatusCode property to see which FTP error you have.
Here's the code I ended up with:
public static bool FileExists(string host, string username, string password, string filename)
{
// create FTP request
FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://" + host + "/" + filename);
request.Credentials = new NetworkCredential(username, password);
// we want to get date stamp - to see if the file exists
request.Method = WebRequestMethods.Ftp.GetDateTimestamp;
try
{
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
var lastModified = response.LastModified;
// if we get the last modified date then the file exists
return true;
}
catch (WebException ex)
{
var ftpResponse = (FtpWebResponse)ex.Response;
// if the status code is 'file unavailable' then the file doesn't exist
// may be different depending upon FTP server software
if (ftpResponse.StatusCode == FtpStatusCode.ActionNotTakenFileUnavailable)
{
return false;
}
// some other error - like maybe internet is down
throw;
}
}
I faced a similar situation:
I was trying to read raw response in case of an HTTP error consuming a SOAP service, using BasicHTTPBinding.
However, when reading the response using GetResponseStream(), got the error:
Stream not readable
So, this code worked for me:
try
{
response = basicHTTPBindingClient.CallOperation(request);
}
catch (ProtocolException exception)
{
var webException = exception.InnerException as WebException;
var rawResponse = string.Empty;
var alreadyClosedStream = webException.Response.GetResponseStream() as MemoryStream;
using (var brandNewStream = new MemoryStream(alreadyClosedStream.ToArray()))
using (var reader = new StreamReader(brandNewStream))
rawResponse = reader.ReadToEnd();
}
You can also use this library which wraps HttpWebRequest and Response into simple methods that return objects based on the results. It uses some of the techniques described in these answers and has plenty of code inspired by answers from this and similar threads. It automatically catches any exceptions, seeks to abstract as much boiler plate code needed to make these web requests as possible, and automatically deserializes the response object.
An example of what your code would look like using this wrapper is as simple as
var response = httpClient.Get<SomeResponseObject>(request);
if(response.StatusCode == HttpStatusCode.OK)
{
//do something with the response
console.Writeline(response.Body.Id); //where the body param matches the object you pass in as an anonymous type.
}else {
//do something with the error
console.Writelint(string.Format("{0}: {1}", response.StatusCode.ToString(), response.ErrorMessage);
}
Full disclosure
This library is a free open source wrapper library, and I am the author of said library. I make no money off of this but have found it immensely useful over the years and am sure anyone who is still using the HttpWebRequest / HttpWebResponse classes will too.
It is not a silver bullet but supports get, post, delete with both async and non-async for get and post as well as JSON or XML requests and responses. It is being actively maintained as of 6/21/2020
Sometimes ex.Response also throws NullReferenceException so below is the best way to handle
catch (WebException ex)
{
using (var stream = ex?.Response?.GetResponseStream())
if(stream != null)
using (var reader = new StreamReader(stream))
{
Console.WriteLine(reader.ReadToEnd());
}
// todo...
}
catch (Exception ex)
{
// todo...
}
**Answer Updated on 14-03-2022**
HttpWebRequest myHttprequest = null;
HttpWebResponse myHttpresponse = null;
try
{
myHttpRequest = (HttpWebRequest)WebRequest.Create(URL);
myHttpRequest.Method = "POST";
myHttpRequest.ContentType = "application/x-www-form-urlencoded";
myHttpRequest.ContentLength = urinfo.Length;
StreamWriter writer = new StreamWriter(myHttprequest.GetRequestStream());
writer.Write(urinfo);
writer.Close();
myHttpresponse = (HttpWebResponse)myHttpRequest.GetResponse();
if (myHttpresponse.StatusCode == HttpStatusCode.OK)
{
//Success code flow
}
myHttpresponse.Close();
}
catch(WebException e) {
Console.WriteLine("This program is expected to throw WebException on successful run."+
"\n\nException Message :" + e.Message);
if(e.Status == WebExceptionStatus.ProtocolError) {
Console.WriteLine("Status Code : {0}",
((HttpWebResponse)e.Response).StatusCode);
Console.WriteLine("Status Description : {0}",
((HttpWebResponse)e.Response).StatusDescription);
}
**Updated Answer with try catch block**
[docs.microsoft][1]

POST Json String to Remote PHP Script using Json.NET

I am encountering an unusually strange behavior when POSTing a Json string to a PHP webserver. I use the JsonTextWriter object to create the Json string. I then send the Json string as a POST request. Please see comments. The HTML response in the code is returning the correct output, but when viewed in a browser, the web page displays either NULL or array(0) { }.
private void HttpPost(string uri, string parameters)
{
WebRequest webRequest = WebRequest.Create(uri);
webRequest.ContentType = "application/x-www-form-urlencoded"; // <- Should this be "application/json" ?
webRequest.Method = "POST";
byte[] bytes = Encoding.UTF8.GetBytes(parameters);
string byteString = Encoding.UTF8.GetString(bytes);
Stream os = null;
try
{ // Send the Post Data
webRequest.ContentLength = bytes.Length;
os = webRequest.GetRequestStream();
os.Write(bytes, 0, bytes.Length);
Console.WriteLine(String.Format(#"{0}", byteString)); // <- This matches the Json object
}
catch (WebException ex)
{ //Handle Error }
try
{ // Get the response
WebResponse webResponse = webRequest.GetResponse();
if (webResponse == null) { return null; }
StreamReader sr = new StreamReader(webResponse.GetResponseStream());
Console.WriteLine(sr.ReadToEnd().Trim()); // <- Server returns string response (full HTML page)
}
catch (WebException ex)
{ //Handle Error }
}
Relevant PHP code on the server:
$json = json_encode($_POST); # Not 'standard way'
var_dump(json_decode($json));
Any suggestions would be greatly appreciated.
Thanks
Try using "application/json" as the content type. Also, check the request logs or maybe do a port 80 trace if you can to view what's being sent to the server in the request body.
You can also narrow the scope of the problem -- is it the C# code or the PHP code that's bad -- by writing a quick JQuery ajax function that sends some JSON to the PHP server. This isolation of the PHP code from the C# code will tell you if the PHP is at least working correctly. If it is, then the problem is in the C# code.

Categories

Resources