Search code examples
c#dotnet-httpclientrequest-headers

Post with HttpClient and custom Accept / Encoding headers


I need to consume a 3rd party api of an internal system, which expects the following headers:

Accept application/json;charset=iso-8859-1
Content-Type application/json;charset=iso-8859-1

In order to do this I've cobbled together the following piece of code:

public async Task<bool> CreateOrDeleteFolder(CreateFolderRequestBody body)
{
   var request = new HttpRequestMessage(HttpMethod.Post, $"{BaseAddress}/testFolder.php");
   request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")
   {
      CharSet = "iso-8859-1"
   });
   
   var isoEncoding = Encoding.GetEncoding("iso-8859-1");
   var payload = new StringContent(JsonConvert.SerializeObject(body), isoEncoding, "application/json");

   request.Content = payload;
   HttpResponseMessage responseMessage = null;
   
   responseMessage = await _client.SendAsync(request);
  
   responseMessage.EnsureSuccessStatusCode();
   var responseBody = await responseMessage.Content.ReadAsStringAsync();
   //do something with the body
   return true;
}

This produces the following request:

POST http://somewhere.to/testFolder.php HTTP/1.1
Accept: application/json; charset=iso-8859-1
Content-Type: application/json; charset=iso-8859-1
Host: somwhere.to
Content-Length: 57
Expect: 100-continue
Connection: Keep-Alive

Apparently the additional whitespace in the headers between the semicolon and the charset produces a response stating invalid header values.

How can I manipulate those header values to not contain those white spaces?


Solution

  • I've botched a workaround together by inherting from MediaTypeHeaderValue:

    public class TrimmedMediaTypeHeaderValue : MediaTypeHeaderValue
    {
       public TrimmedMediaTypeHeaderValue(string mediaType) :base(mediaType)
       {
    
       }
    
       public override string ToString() 
            => string.IsNullOrEmpty(CharSet)
               ? MediaType
               : $"{MediaType};charset={CharSet}";
    }
    

    Since the docs did not specify any method that would build the header string together I just assumed it would be ToString() and indeed - it is. So this now produces a header value, without a whitespace between the ; and the charset.

    Be aware, that this class has only one constructor instead of the 2 of the base class. So if you want to use this, you might need to add another one in.