C#: Getting message body from HTTP 409 Conflict response - c#

I am trying to get message body from web service (located at http://www.ekkuli.net/conflict_call.php), which is returning 'Transfer-Encoding: chunked' tag and 409 Conflict response using the following code:
String webAddr = "http://www.ekkuli.net/conflict_call.php";
var httpWebRequest = (HttpWebRequest)WebRequest.Create(webAddr);
httpWebRequest.ContentType = "application/json; charset=utf-8";
httpWebRequest.Method = "POST";
httpWebRequest.ServicePoint.Expect100Continue = false;
httpWebRequest.Accept = "application/json";
httpWebRequest.KeepAlive = true;
try {
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream())) {
String myJson = "{ \"method\" : \"just testing\" }";
streamWriter.Write(myJson);
streamWriter.Flush();
}
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream())) {
var responseText = streamReader.ReadToEnd();
}
} catch (WebException ex) { // Catch 409 Conflict response
try {
// Try to get message body from 409 Response
var s = ex.Response.GetResponseStream();
var sr = new System.IO.StreamReader(s);
var content = sr.ReadToEnd(); // THIS THROWS AN EXCEPTION
} catch (Exception excep) {
// Exception! Error getting response stream (ReadAsync): ReceiveFailure Value cannot be null.
}
}
Is there any way to get response body from 409 Conflict -response, when server is returning 'Transfer-encoding: Chuncked' -header? If this header is disabled and Content-length is returned instead, everything works fine, but in this case I cannot modify the server code.
Same problem occurs, when trying with RestSharp -library (it returns status code 0 and message body 0).
I am using Mono (for Mac).

Related

How do I read a custom error message returned when HttpWebRequest.GetResponse throws a WebException?

I've a NET.Core API with simple test method:
public async Task<IActionResult> TestApi()
{
try
{
throw new UnauthorizedAccessException("My custom error");
return Ok();
}
catch (UnauthorizedAccessException ex)
{
return StatusCode(401,ex.Message);
}
catch (Exception ex)
{
throw;
}
}
I need to retrieve the message from a client like this:
var request = WebRequest.Create($"{baseUrl}{url}") as HttpWebRequest;
request.Method = "POST";
request.ContentType = "application/json";
request.Expect = "application/json";
request.ContentLength = 0;
if (parameters != null)
{
request.ContentLength = serializedObject.Length;
using (var writer = new StreamWriter(request.GetRequestStream()))
{
writer.Write(serializedObject);
}
}
var response = request.GetResponse() as HttpWebResponse;
var responseEncoding = Encoding.GetEncoding(response.CharacterSet);
using (var sr = new StreamReader(response.GetResponseStream(), responseEncoding))
{
var result = sr.ReadToEnd();
return JsonConvert.DeserializeObject<T>(result);
}
Now request.GetResponse() as HttpWebResponse returns me:
The remote server returned an error: (401) Unauthorized.
instead of My custom error. Can someone point me in the right direction?
Here's a pared-down example which reads your custom message. Your message is returned in the response stream.
try
{
var response = request.GetResponse() as HttpWebResponse;
}
catch (WebException ex) // this exception is thrown because of the 401.
{
var responseStream = ex.Response.GetResponseStream();
using (var reader = new StreamReader(responseStream))
{
var message = reader.ReadToEnd();
}
}
Return an ActionResult
Task<ActionResult>
You can then wrap up the unauthorized error in an UnauthorizedObjectResult
return Unauthorized(new UnauthorizedObjectResult(errorModel));

Why does my API POST Request keep failing?

I am doing an API Post request and cant seem to get it to work. I always get a sendFailure webexception and the response for the exception is always null so catching the exception is useless. It keeps happening when I try to get the httpWebResponse. I noticed too the request.contentlength gave errors at postream getrequeststream so i commented it out. Test.json is the file I use for the request body. I also tested this on different API testers by including the URL, body, and content-type in the header and they worked. I just cant seem to code it for myself. The credentials work I just dont know if im doing the request correctly?
JSON File:
{
"email": "abc#123.com",
"password": "12345",
"facilityNumber": "987654"
}
string filepath = "test.json";
string result = string.Empty;
using (StreamReader r = new StreamReader(filepath))
{
var json = r.ReadToEnd();
var jobj = JObject.Parse(json);
foreach (var item in jobj.Properties())
{
item.Value = item.Value.ToString().Replace("v1", "v2");
}
result = jobj.ToString();
Console.WriteLine(result);
}
try
{
string setupParameters;
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create("https://www.test.com/abcde");
request.AllowAutoRedirect = true;
setupParameters = result;
ServicePointManager.ServerCertificateValidationCallback = (s, cert, chain, ssl) => true;
ASCIIEncoding encoding = new ASCIIEncoding();
var postData = setupParameters;
request.Method = "POST";
request.ContentType = "application/json";
byte[] data = encoding.GetBytes(postData);
//request.ContentLength = data.Length;
using (StreamWriter postStream = new StreamWriter(request.GetRequestStream()))//error if uncomment contentlength
{
postStream.Write(postData);
postStream.Flush();
postStream.Close();
}
HttpWebResponse wr = (HttpWebResponse)request.GetResponse();//error occurs
Stream receiveStream = wr.GetResponseStream();
StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8);
}
catch (WebException ex)
{
if (ex.Response != null)
{
using (var errorResponse = (HttpWebResponse)ex.Response)
{
using (var reader = new StreamReader(errorResponse.GetResponseStream()))
{
string error = reader.ReadToEnd();
result = error;
}
}
}
I suggest modifiying your request to follow this format. Especially pay attention to the request.Method and request.ContentType which have caught me out multiple times.
Also, handling the response is easier this way.
try
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(YOURURL);
request.ContentType = "application/json; charset=utf8";
request.Headers.Add(ADD HEADER HERE IF YOU NEED ONE);
request.Method = WebRequestMethods.Http.Post; // IMPORTANT
using (var streamWriter = new StreamWriter(request.GetRequestStream()))
{
streamWriter.Write(JsonConvert.SerializeObject(JSONBODYSTRING));
// I USUALLY YOU JSONCONVERT HERE TO SIMPLY SERIALIZE A STRING CONTAINING THE JSON INFO.
//BUT I GUESS YOUR METHOD WOULD ALSO WORK
streamWriter.Flush();
streamWriter.Close();
}
WebResponse response = request.GetResponse();
using (var streamReader = new StreamReader(response.GetResponseStream()))
{
string result = streamReader.ReadToEnd();
// DO WHATEVER YOU'D LIKE HERE
}
} catch (Exception ex)
{
// HANDLE YOUR EXCEPTIONS
}

Trying to connect to the Dropbox API v2 using C# Receive 400 error on all attempts

The new Dropbox API documentation is at:
https://blogs.dropbox.com/developers/2015/04/a-preview-of-the-new-dropbox-api-v2/
I'm trying to execute a simple metadata call, but am having very little success. Here's the code I'm using:
private void go()
{
var httpWebRequest = (HttpWebRequest)WebRequest.Create("https://api.dropbox.com/2-beta/files/get_metadata");
httpWebRequest.ContentType = "text/json";
httpWebRequest.Method = "POST";
httpWebRequest.Headers.Add("Authorization: Bearer xxxxxxxxxxxxxxxxxxx");
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
string json = "{\"path\": \"/avatar_501.png\"}";
streamWriter.Write(json);
streamWriter.Flush();
streamWriter.Close();
}
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
this.TextBox1.Text = result;
}
}
Any help would be massively appreciated!
If you try this code, you'll see the body of the 400 response, which tells you that text/json is not a valid Content-Type. I converted your code to a console app, and I'm using Newtonsoft.Json for the JSON serialization. Otherwise, the only difference between your code and mine is the addition of exception handling to get the body of the 400.
class Program
{
static void Main(string[] args)
{
var httpWebRequest = (HttpWebRequest)WebRequest.Create("https://api.dropbox.com/2-beta/files/get_metadata");
httpWebRequest.ContentType = "text/json";
httpWebRequest.Method = "POST";
httpWebRequest.Headers.Add("Authorization: Bearer <REDACTED>");
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
streamWriter.Write(JsonConvert.SerializeObject(new {
path = "/avatar_501.png"
}));
}
HttpWebResponse response;
try
{
response = (HttpWebResponse)httpWebRequest.GetResponse();
}
catch (WebException e)
{
response = (HttpWebResponse)e.Response;
}
Console.WriteLine("Status code: {0}", (int)response.StatusCode);
using (var streamReader = new StreamReader(response.GetResponseStream()))
{
Console.WriteLine(streamReader.ReadToEnd());
}
Console.ReadLine();
}
}
The output is as follows:
Status code: 400
Error in call to API function "files/get_metadata": Bad HTTP "Content-Type" header: "text/json". Expecting one of "application/json", "application/json; charset=utf-8", "text/plain; charset=dropbox-cors-hack".
Changing the Content-Type to application/json causes the call to succeed.

WEBException was unhandled: The remote server returned an error: (500) Internal Server Error

I am implementing REST service and I am getting the above error. I searched a lot and used different methods to resolve this error but no luck. The service is working fine when I am using Postman or fiddler.
Here is my code :
try
{
string content = string.Empty;
var httpWebRequest = (HttpWebRequest)WebRequest.Create(new Uri("https://api.MYDOMAIN.com/servlet/Year"));
httpWebRequest.Method = "POST";
string parsedContent = "{\"securitykey\":\"KEY\"}";
var data = JObject.Parse(parsedContent);
Byte[] bytes = Encoding.UTF8.GetBytes(data.ToString());
httpWebRequest.ContentLength = bytes.Length;
httpWebRequest.ContentType = "application/json";
Stream newStream = httpWebRequest.GetRequestStream();
newStream.Write(bytes, 0, bytes.Length);
newStream.Close();
var response = (HttpWebResponse)httpWebRequest.GetResponse();
var stream = response.GetResponseStream();
if (stream != null)
{
var sr = new StreamReader(stream);
content = sr.ReadToEnd();
}
}
catch (WebException ex)
{
throw;
}
So in the above code I tried with :
httpWebRequest.ContentType = "application/x-www-form-urlencoded";
HttpUtility.UrlEncode()
I also tried the below code but it is giving me the same error :
using (var client = new WebClient())
{
client.Headers[HttpRequestHeader.ContentType] = "application/json";
result = client.UploadString("https://api.MYDOMAIN.com/servlet/Year", "POST", "{\"securitykey\":\"MYKEY\"}");
}
I added the security key in raw header as httpWebRequest.Headers.Add("{\"securitykey\":\"MYKEY\"}") but still no luck.
Really appreciate if I can get some help.
After a lot of RND I tried doing this in PHP, so it gave me an error as UserAgent is required. I added httpWebRequest.UserAgent and it worked. This error was never displayed in WebException.

Json POST request to the server but server respond (400) Bad Request

I want to use google api for creation of gmail user account. I am sending JSON request to server for getting authorization code but I got these error in httpwebresponse :-
Exception Details: System.Net.WebException: The remote server returned an error: (400) Bad Request
var request = (HttpWebRequest)WebRequest.Create(#"https://accounts.google.com/o/oauth2/auth");
request.Method = "POST";
request.ContentType = "text/json";
request.KeepAlive = false;
//request.ContentLength = 0;
using (StreamWriter streamWriter = new StreamWriter(request.GetRequestStream()))
{
string json = "{\"scope\":\"https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile\"," + "\"state\":\"%2Fprofile\"," + "\"redirect_uri\":\"http://gmailcheck.com/response.aspx\"," + "\"response_type\":\"code\"," + "\"client_id\":\"841994137170.apps.googleusercontent.com\"}";
streamWriter.Write(json);
// streamWriter.Flush();
//streamWriter.Close();
}
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
StreamReader responsereader = new StreamReader(response.GetResponseStream());
var responsedata = responsereader.ReadToEnd();
//Session["responseinfo"] = responsereader;
//testdiv.InnerHtml = responsedata;
}
}
As soon as you get an exception, you have to read the actual responce from server there should be something helpfull. Like an error description or extended status code...
For Instance:
try
{
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
... your code goes here....
}
catch (WebException ex)
{
using (WebResponse response = ex.Response)
{
var httpResponse = (HttpWebResponse)response;
using (Stream data = response.GetResponseStream())
{
StreamReader sr = new StreamReader(data);
throw new Exception(sr.ReadToEnd());
}
}
}

Categories

Resources