Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

System.InvalidOperationException: Misused header name. Make sure request headers are used with HttpRequestMessage, response headers with HttpResponseMessage, and content headers with HttpContent objects. #33039

Closed
HASSEN-MEDDEB-ATOS opened this issue Mar 2, 2020 · 32 comments

Comments

@HASSEN-MEDDEB-ATOS
Copy link

HASSEN-MEDDEB-ATOS commented Mar 2, 2020

Hello,

I have migarted my project from .NET Framework to .NET Core, and when i call WS i get error

System.InvalidOperationException: Misused header name. Make sure request headers are used with HttpRequestMessage, response headers with HttpResponseMessage, and content headers with HttpContent objects.
at System.Net.Http.Headers.HttpHeaders.GetHeaderDescriptor(String name)
at System.Net.Http.Headers.HttpHeaders.Add(String name, String value)



Cordially
@Dotnet-GitSync-Bot Dotnet-GitSync-Bot added area-System.Net.Http untriaged New issue has not been triaged by the area owner labels Mar 2, 2020
@HASSEN-MEDDEB-ATOS
Copy link
Author

@davidsh any suggestion please

@davidsh
Copy link
Contributor

davidsh commented Mar 2, 2020

@davidsh David Shulman FTE any suggestion please

//request.Headers.Remove("Content-Type");

Entity body related headers such as 'Content-Type', 'Content-Length' should be added to the Content.Headers collection of HttpRequestMessage. That assumes that you are also adding an HttpContent object as well since you are trying to probably post some content.

request.Content.Headers.Add("Content-Type", "application/json;charset=UTF-8");

@HASSEN-MEDDEB-ATOS
Copy link
Author

Thank you for your repsonse
i get now this error :/

System.NullReferenceException: Object reference not set to an instance of an object.
   at VSMP_Contracts.CTR_WS_Connection.CustomDelegatingHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) in C:\Git\VSMP_Data_Integration\VSMP_Data_Integration\VSMP_Contracts_Import\CTR_WS_Connection.cs:line 154
   at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)

Cordailly

@HASSEN-MEDDEB-ATOS
Copy link
Author

using (HMACSHA1 hmac = new HMACSHA1(_secretKeyUTF8))
                {
                    byte[] Datebytes = Encoding.UTF8.GetBytes(Date);
                    byte[] hashedValue = hmac.ComputeHash(Datebytes);
                    string Signature = Convert.ToBase64String(hashedValue);
                    string Url_Encoded_Signature = UpperCaseUrlEncode(Signature);

                    request.Headers.Add("Authorization", string.Format("Signature keyId=\"{0}\",algorithm=\"{1}\",signature=\"{2}\"", _applicationId, "hmac-sha1", Url_Encoded_Signature));

                    //var invalidHeaders = (HashSet<string>)typeof(HttpHeaders).GetField("invalidHeaders", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(request.Headers);
                    //invalidHeaders.Remove("Content-Type");
                    //request.Headers.Remove("Content-Type");
                    request.Content.Headers.Add("Content-Type", "application/json;charset=UTF-8");
                    request.Headers.TryAddWithoutValidation("Date", utcFormattedDate);
                }
                response = await base.SendAsync(request, cancellationToken);
                return response;
``````

@HASSEN-MEDDEB-ATOS
Copy link
Author

@davidsh Can you invetigate please

@HASSEN-MEDDEB-ATOS
Copy link
Author

System.NullReferenceException: Object reference not set to an instance of an object, when i used request.Content.Headers.Remove("Content-Type");

using (HMACSHA1 hmac = new HMACSHA1(_secretKeyUTF8))
                {
                    byte[] Datebytes = Encoding.UTF8.GetBytes(Date);
                    byte[] hashedValue = hmac.ComputeHash(Datebytes);
                    string Signature = Convert.ToBase64String(hashedValue);
                    string Url_Encoded_Signature = UpperCaseUrlEncode(Signature);
                    var field = typeof(HttpRequestHeaders).GetField("invalidHeaders",BindingFlags.NonPublic | BindingFlags.Static)?? typeof(HttpRequestHeaders).GetField("s_invalidHeaders", BindingFlags.NonPublic | BindingFlags.Static);
                    if (field != null)
                    {
                        var invalidFields = (HashSet<string>)field.GetValue(null);
                        invalidFields.Remove("Content-Type");
                    }
                    request.Content.Headers.Remove("Content-Type");
                    request.Content.Headers.Add("Content-Type", "application/json;charset=UTF-8");
                    request.Content.Headers.TryAddWithoutValidation("Date", utcFormattedDate);
                }
                response = await base.SendAsync(request, cancellationToken);
                return response;

@stephentoub
Copy link
Member

You need to set Content to something. The null ref is from your method trying to call something off of the Content property, which will return null until you set it to something non-null.

@davidsh
Copy link
Contributor

davidsh commented Mar 2, 2020

@HASSEN-MEDDEB-ATOS

Why do you want to set the 'Content-Type' header at all?

If you are trying to control the HTTP response body encoding, then you should set the 'Accept-Encoding' header instead.

@HASSEN-MEDDEB-ATOS
Copy link
Author

HASSEN-MEDDEB-ATOS commented Mar 2, 2020

thnaks for all response but still same error,

using (HMACSHA1 hmac = new HMACSHA1(_secretKeyUTF8))
                {
                    byte[] Datebytes = Encoding.UTF8.GetBytes(Date);
                    byte[] hashedValue = hmac.ComputeHash(Datebytes);
                    string Signature = Convert.ToBase64String(hashedValue);
                    string Url_Encoded_Signature = UpperCaseUrlEncode(Signature);
                    var field = typeof(HttpRequestHeaders).GetField("invalidHeaders",BindingFlags.NonPublic | BindingFlags.Static)?? typeof(HttpRequestHeaders).GetField("s_invalidHeaders", BindingFlags.NonPublic | BindingFlags.Static);
                    if (field != null)
                    {
                        var invalidFields = (HashSet<string>)field.GetValue(null);
                        invalidFields.Remove("Content-Type");
                    }
                    request.Content.Headers.Add("Accept", "application/json");
                    request.Content.Headers.Add("Content-Type", "application/json;charset=UTF-8");
                    request.Content.Headers.TryAddWithoutValidation("Date", utcFormattedDate);
                }
                response = await base.SendAsync(request, cancellationToken);
                return response;
            }`
````

@stephentoub
Copy link
Member

still same error

Where are you setting request.Content?

@HASSEN-MEDDEB-ATOS
Copy link
Author

request.Content.Headers.Add("Content-Type", "application/json;charset=UTF-8");
request.Content.Headers.TryAddWithoutValidation("Date", utcFormattedDate);

@stephentoub
Copy link
Member

stephentoub commented Mar 2, 2020

No, where are you actually setting the Content property, e.g.

request.Content = something;

? If you don't do that, it will return null.

@HASSEN-MEDDEB-ATOS
Copy link
Author

HASSEN-MEDDEB-ATOS commented Mar 2, 2020

https://docs.microsoft.com/fr-fr/aspnet/web-api/overview/advanced/http-message-handlers
but accroding to this article we don't need to initialize request.Content ?

@HASSEN-MEDDEB-ATOS
Copy link
Author

My code work well using .NET Framework

@davidsh
Copy link
Contributor

davidsh commented Mar 2, 2020

but according to this article we don't need to initialize request.Content ?

You must create a .Content object if you plan on adding content related headers to the request object like 'Content-Type'.

Also, you didn't answer my question here about why you want to use 'Content-Type' header at all.

@HASSEN-MEDDEB-ATOS
Copy link
Author

i used Content_Type to specifies to the server what data it should expect

@davidsh
Copy link
Contributor

davidsh commented Mar 2, 2020

i used Content_Type to specifies to the server what data it should expect

Ok. That implies you are sending data to the server? So, where is the data that you're sending? You usually create an HttpRequestMessage with the .Content property set to an object. But where is that code? Currently, .Content is null. So, that means you aren't sending any data (no request body).

@HASSEN-MEDDEB-ATOS
Copy link
Author

No in this case i need to get Data from server

@HASSEN-MEDDEB-ATOS
Copy link
Author

 request.Content = new StringContent(string.Empty, Encoding.UTF8, "application/json");
                using (HMACSHA1 hmac = new HMACSHA1(_secretKeyUTF8))
                {
                    byte[] Datebytes = Encoding.UTF8.GetBytes(Date);
                    byte[] hashedValue = hmac.ComputeHash(Datebytes);
                    string Signature = Convert.ToBase64String(hashedValue);
                    string Url_Encoded_Signature = UpperCaseUrlEncode(Signature);
                    var field = typeof(HttpRequestHeaders).GetField("invalidHeaders",BindingFlags.NonPublic | BindingFlags.Static)?? typeof(HttpRequestHeaders).GetField("s_invalidHeaders", BindingFlags.NonPublic | BindingFlags.Static);
                    if (field != null)
                    {
                        var invalidFields = (HashSet<string>)field.GetValue(null);
                        invalidFields.Remove("Content-Type");
                    }
                    request.Headers.Remove("Content-Type");
                    request.Headers.Add("Content-Type", "application/json;charset=UTF-8");
                    request.Headers.Add("Content-Encoding", "identity");
                    request.Headers.TryAddWithoutValidation("Date", utcFormattedDate);
                }
                response = await base.SendAsync(request, cancellationToken);
                return response;

``````

@HASSEN-MEDDEB-ATOS
Copy link
Author

public async static Task<List<Contract>> GetContracts(string URL, string startDate, string EndDate)
        {
            List<Contract> ListContrats = new List<Contract>();                                 //liste allant contenir des pages de contrats (ou des objets "Contract")           
            int startIndex = 0;
            int NbContracts = 0;
            try
            {
                CustomDelegatingHandler customDelegatingHandler = new CustomDelegatingHandler();

                HttpClient client = HttpClientFactory.Create(customDelegatingHandler);
                var watch = System.Diagnostics.Stopwatch.StartNew();

                string urlAppelWS = URL + "&startDate=" + startDate + "&endDate=" + EndDate + "&count=100";

                while (!string.IsNullOrEmpty(urlAppelWS)) //appel du web service en boucle (pour le parcours de la pagination) jusqu'à ce que l'on ait plus de page suivante
                {
                    LogHelper.Writer("" + urlAppelWS);

                    HttpResponseMessage response = await client.GetAsync(urlAppelWS);
                    LogHelper.Writer("" + response);

                    if (response.StatusCode != HttpStatusCode.OK)
                        throw new Exception();

                    string responsedata = await response.Content.ReadAsStringAsync();

                    Contract Contrats = JsonConvert.DeserializeObject<Contract>(responsedata);
                    if (Contrats.results.Length == 0)
                    {
                        break;
                    }
                    ListContrats.Add(Contrats);        //ajout de la réponse en page de contrats dans la liste
                    urlAppelWS = string.IsNullOrEmpty(Contrats.nextResults) ? string.Empty : URL + Contrats.nextResults.Split('?')[1];
                    Console.WriteLine("Nouvelle page de contrats : {0} contrats", Contrats.results.Length);
                    NbContracts += Contrats.results.Length;
                }
                watch.Stop();
                var elapsedMs = watch.ElapsedMilliseconds;
                LogHelper.Writer(string.Format("Temps d'extraction des contrats depuis le web service : {0} ms soit {1} s", elapsedMs, elapsedMs / 1000));

                if (NbContracts != 0)
                    LogHelper.Writer(string.Format("{0} contrats extrais répartis sur {1} pages", NbContracts, startIndex));
            }
            catch (NullReferenceException ex)
            {
                LogHelper.Writer("Erreur (référence nulle) lors de l'import des contrats depuis le web service, message de l'erreur : " + Environment.NewLine + ex.ToString());
                throw ex;
            }
            catch (Exception ex)
            {
                LogHelper.Writer("Erreur lors de l'import des contrats depuis le web service, message de l'erreur : " + ListContrats.Count + Environment.NewLine + ex.ToString());
                throw ex;
            }
            return ListContrats;
        }
``````

@davidsh
Copy link
Contributor

davidsh commented Mar 2, 2020

If you need to set 'Content-Type', you should set it on your request.Content.Headers object. However, looking at your code, you probably already are setting it?

request.Content = new StringContent(string.Empty, Encoding.UTF8, "application/json");

No in this case i need to get Data from server

This statement tells me you want to control the data that the server sends to the client. So, you should be setting the 'Accept-Encoding' header on the HttpRequestMessage instead. That tells a server what kind of response body data to send back to the client.

@HASSEN-MEDDEB-ATOS
Copy link
Author

 request.Content = new StringContent(string.Empty, Encoding.UTF8, "application/json");
                using (HMACSHA1 hmac = new HMACSHA1(_secretKeyUTF8))
                {
                    byte[] Datebytes = Encoding.UTF8.GetBytes(Date);
                    byte[] hashedValue = hmac.ComputeHash(Datebytes);
                    string Signature = Convert.ToBase64String(hashedValue);
                    string Url_Encoded_Signature = UpperCaseUrlEncode(Signature);
                    var field = typeof(HttpRequestHeaders).GetField("invalidHeaders",BindingFlags.NonPublic | BindingFlags.Static)?? typeof(HttpRequestHeaders).GetField("s_invalidHeaders", BindingFlags.NonPublic | BindingFlags.Static);
                    if (field != null)
                    {
                        var invalidFields = (HashSet<string>)field.GetValue(null);
                        invalidFields.Remove("Content-Type");
                    }
                    request.Content.Headers.Add("Content-Type", "application/json;charset=UTF-8");
                    request.Content.Headers.Add("Content-Encoding", "identity");
                    request.Headers.TryAddWithoutValidation("Date", utcFormattedDate);
                }
                response = await base.SendAsync(request, cancellationToken);
                return response;
            }
``````

@HASSEN-MEDDEB-ATOS
Copy link
Author

HASSEN-MEDDEB-ATOS commented Mar 2, 2020

system.Exception: Exception of type 'System.Exception' was thrown.
at VSMP_Contracts.CTR_WS_Connection.GetContracts(String URL, String startDate, String EndDate)

@HASSEN-MEDDEB-ATOS
Copy link
Author

Misused header name. Make sure request headers are used with HttpRequestMessage, response headers with HttpResponseMessage, and content headers with HttpContent objects.
at System.Net.Http.Headers.HttpHeaders.GetHeaderDescriptor(String name)
at System.Net.Http.Headers.HttpHeaders.Add(String name, String value)

  request.Content = new StringContent(string.Empty, Encoding.UTF8, "application/json");
                using (HMACSHA1 hmac = new HMACSHA1(_secretKeyUTF8))
                {
                    byte[] Datebytes = Encoding.UTF8.GetBytes(Date);
                    byte[] hashedValue = hmac.ComputeHash(Datebytes);
                    string Signature = Convert.ToBase64String(hashedValue);
                    string Url_Encoded_Signature = UpperCaseUrlEncode(Signature);
                    request.Headers.Add("Authorization", string.Format("Signature keyId=\"{0}\",algorithm=\"{1}\",signature=\"{2}\"", _applicationId, "hmac-sha1", Url_Encoded_Signature));

                    var field = typeof(HttpRequestHeaders).GetField("invalidHeaders",BindingFlags.NonPublic | BindingFlags.Static)?? typeof(HttpRequestHeaders).GetField("s_invalidHeaders", BindingFlags.NonPublic | BindingFlags.Static);
                    if (field != null)
                    {
                        var invalidFields = (HashSet<string>)field.GetValue(null);
                        invalidFields.Remove("Content-Type");
                    }
                    request.Content.Headers.Add("Accept-Encoding", "gzip");
                    request.Headers.TryAddWithoutValidation("Date", utcFormattedDate);
                }
                response = await base.SendAsync(request, cancellationToken);
                return response;
``````

@davidsh
Copy link
Contributor

davidsh commented Mar 2, 2020

request.Content.Headers.Add("Accept-Encoding", "gzip");

If you want to use 'Accept-Encoding', that header goes into the main request.Headers collection.

@HASSEN-MEDDEB-ATOS
Copy link
Author

system.Exception: Exception of type 'System.Exception' was thrown.
at VSMP_Contracts.CTR_WS_Connection.GetContracts(String URL, String startDate, String EndDate)

@HASSEN-MEDDEB-ATOS
Copy link
Author

Can you came skype please for 2 minutes please

@HASSEN-MEDDEB-ATOS
Copy link
Author

i have modified my code like this

request.Content = new StringContent(string.Empty, Encoding.UTF8, "application/json");
                using (HMACSHA1 hmac = new HMACSHA1(_secretKeyUTF8))
                {
                    byte[] Datebytes = Encoding.UTF8.GetBytes(Date);
                    byte[] hashedValue = hmac.ComputeHash(Datebytes);
                    string Signature = Convert.ToBase64String(hashedValue);
                    string Url_Encoded_Signature = UpperCaseUrlEncode(Signature);
                    request.Headers.Add("Authorization", string.Format("Signature keyId=\"{0}\",algorithm=\"{1}\",signature=\"{2}\"", _applicationId, "hmac-sha1", Url_Encoded_Signature));

                    var field = typeof(HttpRequestHeaders).GetField("invalidHeaders",BindingFlags.NonPublic | BindingFlags.Static)?? typeof(HttpRequestHeaders).GetField("s_invalidHeaders", BindingFlags.NonPublic | BindingFlags.Static);
                    if (field != null)
                    {
                        var invalidFields = (HashSet<string>)field.GetValue(null);
                        invalidFields.Remove("Content-Type");
                    }
                    request.Headers.Add("Accept-Encoding", "gzip");
                    request.Content.Headers.TryAddWithoutValidation("Date", utcFormattedDate);
                }
                response = await base.SendAsync(request, cancellationToken);
                return response;
``````
i get new error,Newtonsoft.Json.JsonReaderException: Unexpected character encountered while parsing value: �. Path '', line 0, position 0.
   at Newtonsoft.Json.JsonTextReader.ParseValue()
   at Newtonsoft.Json.JsonReader.ReadAndMoveToContent()
   at Newtonsoft.Json.JsonReader.ReadForType(JsonContract contract, Boolean hasConverter)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
   at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
   at Newtonsoft.Json.JsonSerializer.Deserialize(JsonReader reader, Type objectType)
   at Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings)
   at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value, JsonSerializerSettings settings)

@HASSEN-MEDDEB-ATOS
Copy link
Author

                string responsedata = await response.Content.ReadAsStringAsync();

@HASSEN-MEDDEB-ATOS
Copy link
Author

HASSEN-MEDDEB-ATOS commented Mar 2, 2020

my request return this messge below
Method: GET, RequestUri: 'https://www.test.com/mediation/v1/recette/vsmp/contracts?&startDate=2019-08-01T08:52:13Z&endDate=2020-03-02T20:28:12Z&count=100', Version: 1.1, Content: System.Net.Http.StringContent, Headers:
{
Authorization: Signature keyId="**********",algorithm="hmac-sha1",signature="********"
Accept-Encoding: gzip
Content-Type: application/json; charset=UTF-8
}
02/03/2020 21:28:13 | StatusCode: 200, ReasonPhrase: 'OK', Version: 1.1, Content: System.Net.Http.HttpConnectionResponseContent, Headers:
{
Date: Mon, 02 Mar 2020 20:28:12 GMT
Server: Apache
Posc_transaction_id: 2cee38a2-56f3-45f4-99ac-65403f57786c
Vary: Accept-Encoding
X-Hub-Project: LaPosteSpring
X-Ratelimit-Limit: 0
X-Ratelimit-Remaining: 0
X-Ratelimit-Reset: 0
Via: 1.1 www.test.com
Transfer-Encoding: chunked
Content-Encoding: gzip
Content-Type: application/json; charset=UTF-8
}

@HASSEN-MEDDEB-ATOS
Copy link
Author

HASSEN-MEDDEB-ATOS commented Mar 2, 2020

I have finally find solution, i don't need to use request.Headers.Add("Accept-Encoding", "gzip");

 request.Content.Headers.Remove("Content-Type");
                    //request.Headers.Add("Accept-Encoding", "gzip");
                    request.Content.Headers.Add("Content-Type", "application/json;charset=UTF-8");

                    request.Content.Headers.TryAddWithoutValidation("Date", utcFormattedDate);`

Thanks for all response @davidsh @stephentoub

@karelz karelz added this to the 5.0.0 milestone Aug 18, 2020
@ghost ghost locked as resolved and limited conversation to collaborators Dec 10, 2020
@karelz karelz removed the untriaged New issue has not been triaged by the area owner label Oct 20, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

5 participants