12

I am using HttpClient to make a POST call by passing header but at some point of time I am getting an error as:

Request headers must contain only ASCII characters.

With stacktrace as:

at System.Net.Http.HttpConnection.WriteStringAsync(String s)
   at System.Net.Http.HttpConnection.WriteHeadersAsync(HttpHeaders headers, String cookiesFromContainer)
   at System.Net.Http.HttpConnection.SendAsyncCore(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.SendWithNtConnectionAuthAsync(HttpConnection connection, HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)
   at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.DiagnosticsHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)

Here is my code:

public HttpWrapper(string endpoint, Func<IDictionary<string, string>> NewHeader)
{
    _httpClient = new HttpClient();
    _httpClient.BaseAddress = new Uri(endpoint);

    if (NewHeader != null)
    {
        var headers = NewHeader();
        foreach (var header in headers)
        {
            _httpClient.DefaultRequestHeaders.TryAddWithoutValidation(header.Key, header.Value);
        }
    }
}

Do I need to do something with header.Value to fix this issue? I was reading online so looks like I need to use Utf-8 here but not sure on how to do it properly?

Update

I got header value like this today and it threw same exception since HttpUtility.HtmlEncode didn't do anything on it. Also I am not sure what is this character <0x94>? Any thoughts why it is happening?

Also I am not sure

enter image description here

5
  • "In order to use non ASCII characters in URI you need to escape them using the %hexcode syntax (see section 2 of RFC 2396)." from stackoverflow.com/a/5251951/5386938 Commented Nov 11, 2020 at 18:44
  • How do I do that @JustinEzequiel? Commented Nov 11, 2020 at 18:45
  • Here's one way Commented Nov 11, 2020 at 19:50
  • What about the accepted answer? Is that correct way as well? @JustinEzequiel Commented Nov 11, 2020 at 19:55
  • If the accepted answer works for you then good. Commented Nov 11, 2020 at 19:56

2 Answers 2

4

You can try to encode header values to HTML:

_httpClient.DefaultRequestHeaders.TryAddWithoutValidation(header.Key, HttpUtility.HtmlEncode(header.Value));

Your string, Ergänzendes will be "Erg&#228;nzendes".

Sign up to request clarification or add additional context in comments.

10 Comments

I tried like this already but it doesn't give me that value - string str = "Ergänzendes"; string val = Convert.ToBase64String(Encoding.UTF8.GetBytes(str)); Console.WriteLine(val); back. Is this the right expectation? It just prints this value RXJnw6RuemVuZGVz
So internally httpclient will convert this base64 encoded string RXJnw6RuemVuZGVz to the way it came back originally? Is my assumptions correct here?
Hmm, it's changing the original text. You can try to encode to HMTL your string. The answer is updated.
It then prints like this - Erg&#228;nzendes. I am not sure if that is the right way?
Yes, this is the correct way. The browsers render the header text to "Ergänzendes ".
|
3

I hope this may help in your specific scenario or others with a similar situation. In my case, my header was containing non ASCII characters as one of the Headers values was generated by creating a sha256 HMAC. That was a requirement from the service I was trying to send my request. So, what I had to do in order to encode those characters into ASCII was just this:

//hashedSignature is the one containing NON ASCII charcters!
string MessageSignatureValue = System.Text.Encoding.ASCII.GetString(hashedSignature); 
httpClient.DefaultRequestHeaders.Add(MessageSignaturField, MessageSignatureValue);

I have just included the importants pieces of code.

So, System.Text.Encoding.ASCII.GetString() method did the trick!

Again, I hope it helps.

4 Comments

I see. So what's the difference between accepted answer and your suggestion? Any thoughts?
You sure this is the right syntax - string MessageSignatureValue = System.Text.Encoding.ASCII.GetString(hashedSignature); ?
Honestly, I have never used HttpUtility. So, I haven't a concrete answer about that. But, from the documentation it states: "Converts a string into an HTML-encoded string." If that works for you there will be no difference, except the in the way I call the method it's telling that you want something encoded to ASCII explicitely. Maybe, it's more esay to understand the purpose. Just a thought. Here you have the link to the ASCIIEncoding
This answer will convert non-recognised characters to '?' so the outputted header value or name, will have a '?' somewhere in the char sequence where the non-ascii char was detected. This might not be the answer some devs are looking for,.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.