Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HttpClient keeps receiving bad request

Tags:

I'm having a hard time resolving my Bad Request responses from a REST api when I'm creating a client using C#. I tested the REST api using Fiddler 2 and executing it there, but when I'm creating the same thing programmatically I get 400 response. Here is my Fiddler composer test:

URL:

https://<third-party-rest-client>/api/v2/job 

Here are my Headers

User-Agent: Fiddler Content-Type: application/json Accept: application/json icSessionId: PomCSBCVU4VgXCJ5     Content-Length: 123 

And here is the body I'm sending a POST request with

{ "@type": "job", "taskId":"0000G20G000000000002", "taskName":"TestReplication", "taskType":"DRS", "callbackURL":"" } 

This POST comes back with a 200 response and a response body, which is perfect, but when I try to simulate the same thing in C# with this code:

public JobResponse RunJob(JobRequest jobRequest)     {         try         {             client = new HttpClient();             client.BaseAddress = new Uri(loggedUser.serverUrl + "/");             client.DefaultRequestHeaders.Clear();             client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));             client.DefaultRequestHeaders.TryAddWithoutValidation("icSessionId", icSessionId);              string message = JsonConvert.SerializeObject(jobRequest);             message = message.Insert(1, "\"@type\": \"job\",");             Console.WriteLine(message);             var response = client.PostAsJsonAsync("api/v2/job", message).Result;             if (response.IsSuccessStatusCode)             {                 return response.Content.ReadAsAsync<JobResponse>().Result;             }             else             {                 var result = response.Content.ReadAsStringAsync().Result;                 Console.WriteLine(result);             }         }         catch (Exception ex)         {             Console.WriteLine(ex);         }         return null;     } 

This comes back as a 400. Does anybody have any ideas what's wrong with my code?

like image 487
Michael Sheely Avatar asked May 22 '16 22:05

Michael Sheely


2 Answers

Okay, I figured out the issue I was having. It seems that Serializing my JSON object into a string first, then posting it with PostAsJsonAsync was leaving all of the escape (\) characters in my object, which was why I received the Bad Request.

The problem here was my first key/value pair in my JSON object had a key with the @ symbol in it. If I try to just PostAsJsonAsync with the object, I lost the @ symbol, which gave me a Bad Request also.

What I ended up doing was Serializing the object into a string as seen above, then I converted it the a Byte Array and then created a new ByteArrayContent object passing in my byte array, adding the ContentType attribute to the ByteArrayContent Headers, then using PostAsync instead of PostAsJsonAsync. This worked perfectly.

Here is the code:

public JobResponse RunInformaticaJob(JobRequest jobRequest)     {         try         {             client = new HttpClient();             client.DefaultRequestHeaders.Clear();             client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));             client.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", "application/json");             client.DefaultRequestHeaders.TryAddWithoutValidation("icSessionId", icSessionId);              string message = JSONSerializer.Serialize(jobRequest);             message = message.Insert(1, "\"@type\": \"job\",");             byte[] messageBytes = System.Text.Encoding.UTF8.GetBytes(message);             var content = new ByteArrayContent(messageBytes);             content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json");              var response = client.PostAsync(loggedUser.serverUrl + "/api/v2/job", content).Result;             if (response.IsSuccessStatusCode)             {                 return response.Content.ReadAsAsync<JobResponse>().Result;             }             else             {                 var result = response.Content.ReadAsStringAsync().Result;                 Console.WriteLine(result);             }         }         catch (Exception ex)         {             Console.WriteLine(ex);         }         return null;     } 

Issue resolved!

like image 152
Michael Sheely Avatar answered Sep 18 '22 21:09

Michael Sheely


In my case examining the content of result.Content.ReadAsStringAsync().Result had the cause of the problem informing of some missing parameters and some parameters with invalid values. Corrected and it's working now.

like image 29
user77 Avatar answered Sep 18 '22 21:09

user77