0
votes

I'm trying to code a middleman API that logs calls and other details from internal users to an external API.

When I try to POST to the external API from my Controller, I get 415 unsupported media type.

I set up my client in the controller constructor like this:

client.BaseAddress = new Uri("https://restapi.***.com/customers/");
client.DefaultRequestHeaders.Clear();
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Add("X-AppSecretToken", Auth.APPSECRETTOKEN);
client.DefaultRequestHeaders.Add("X-AgreementGrantToken", Auth.AGREEMENTGRANTTOKEN);

My POST method looks like this:

var json = JsonConvert.SerializeObject(customer, Formatting.Indented);

using (var stringContent = new StringContent(json))
{
   stringContent.Headers.ContentType.CharSet = "";
   HttpResponseMessage response = await client.PostAsync(client.BaseAddress, stringContent);

   if (!response.IsSuccessStatusCode)
   {
      return StatusCode((int)response.StatusCode);
   }
}

return CreatedAtAction("GetCustomer", new { id = customer.ID }, customer);

I've been looking around and found a lot of comments telling me to use Stringcontent, but I also found a couple of responses saying ByteArrayContent - none of them work.

Can anyone help me?

EDIT: When I run the code with breakpoints it seems like some of the properties in the incoming customer object are set even though I didn't set them in my Postman call.

Example; the external API returns a customernumber when I give it the 5 properties that are obligatory. But when I call my internal API from Postman, sending only those 5 obligatory properties, it autopopulates the customernumber with a 0.

Could this be the source of the error? and how do I tell .net core to not autopopulate the customernumber?

EDIT2: I changed my stringContent to include encoding and used a different overload, so the using line now says

using (var stringContent = new StringContent(json, Encoding.UTF8, "application/json"))

And I removed

stringContent.Headers.ContentType.Charset = "";

to reflect the fact that I tried setting the encoding.

The return code changed from 415 to 400 Bad Request when I changed that.

EDIT3:

Tried NOT serializing with Json.Net, and instead used JObjects and Jproperties;

public async Task<ActionResult<Customer>> PostCustomer([FromBody]Customer customer)
{
   JObject payload = new JObject(
   new JProperty("currency", customer.Currency),
   new JProperty("name", customer.Name),
   new JProperty("customergroup",
       new JObject(new JProperty("customergroupNumber", 
                   customer.CustomerGroup.CustomerGroupNumber)
                  )),
   new JProperty("paymentTerms",
       new JObject(new JProperty("paymentTermsNumber", 
                   customer.PaymentTerms.PaymentTermsNumber)
                  )),
   new JProperty("vatZone", 
       new JObject(new JProperty("vatZoneNumber", 
                   customer.VatZone.VatZoneNumber)
                  ))
   );

using (var stringContent = new StringContent(payload.ToString(), Encoding.UTF8, "application/json"))
   {
    HttpResponseMessage response = await client.PostAsync(client.BaseAddress, stringContent);

    if (!response.IsSuccessStatusCode)
    {
       return StatusCode((int)response.StatusCode);
                }
    }

return CreatedAtAction("GetCustomer", new { id = customer.CustomerNumber }, customer);
}

Still 400 Bad Request

1
The properties for int values will default to 0. For your post if you use PostAsJsonAsync(client.BaseAddress, customer) what happens? - eVolve
I get a 400 Bad Request but fiddler tells me that I send correct JSON - Hans-Henrik Høgsted

1 Answers

0
votes

This is a case of capitalizing - simple really.

My POST request JSON had an object named customergroup - changed it to customerGroup, and it worked.